Quick Start Guide

Get up and running with Ownaudio in minutes. Choose between the low-level Core API for maximum control or the high-level NET API for rapid development.

Introduction

🚀 Native Engine - GC-Free Audio! Ownaudio now uses a high-performance C++ native engine by default, eliminating GC pauses for glitch-free audio. Despite our best efforts with managed code, the .NET Garbage Collector proved insurmountable for professional real-time audio. The native engine is now the default, but managed C# engines remain available for testing/development.
Zero External Dependencies Ownaudio uses native system audio APIs - no external libraries required!

Core

Low-level audio engine with direct platform API access. Perfect for custom audio pipelines and maximum performance.

NET

High-level API with built-in mixing, effects, and multi-track support. Ideal for production applications.

Installation

NuGet Package Manager

Package Manager Console
# For Core API
Install-Package OwnAudioSharp

.NET CLI

Command Line
# For Core API
dotnet add package OwnAudioSharp

Requirements

Ownaudio.Core Usage

Core API Direct access to audio engine. Native engine (default) provides GC-free operation, or use managed engines for pure C# code.

Native Engine (Default - Recommended)

NativeEngine.cs
using Ownaudio.Core;

// Create NATIVE audio engine (DEFAULT - GC-free!)
using var engine = AudioEngineFactory.CreateDefault();
// Or explicitly: AudioEngineFactory.CreateNative();

// Native engine runs outside GC - no audio glitches!
engine.Initialize(AudioConfig.Default);
engine.Start();

Managed Engine (Optional - Pure C#)

ManagedEngine.cs
using Ownaudio.Core;

// Create MANAGED audio engine (pure C#)
// Note: May experience GC-related audio glitches
using var engine = AudioEngineFactory.CreateManaged();

// Or create platform-specific managed engine:
#if WINDOWS
    using var engine = new WasapiEngine();
#elif LINUX
    using var engine = new PulseAudioEngine();
#elif MACOS
    using var engine = new CoreAudioEngine();
#endif

engine.Initialize(AudioConfig.Default);
engine.Start();

Basic Playback

BasicPlayback.cs
using Ownaudio.Core;
using Ownaudio.Decoders;

// Create audio engine with default settings (48kHz, stereo, 512 frames)
using var engine = AudioEngineFactory.CreateDefault();

// Initialize and start the engine
engine.Initialize(AudioConfig.Default);
engine.Start();

// Create decoder for audio file
using var decoder = AudioDecoderFactory.Create(
    "music.mp3",
    targetSampleRate: 48000,
    targetChannels: 2
);

// Decode and play frames
while (true)
{
    var result = decoder.DecodeNextFrame();
    if (result.IsEOF) break;
    
    // Send samples to engine (zero-allocation)
    engine.Send(result.Frame.Samples);
}

// Stop the engine
engine.Stop();

Custom Configuration

CustomConfig.cs
// Create custom audio configuration
var config = new AudioConfig
{
    SampleRate = 44100,
    Channels = 2,
    BufferSize = 256,        // Low latency
    EnableOutput = true,
    EnableInput = false
};

// Create engine with custom config
using var engine = AudioEngineFactory.Create(config);
engine.Initialize(config);
engine.Start();

// Use the engine...
engine.Stop();

Device Management

DeviceManagement.cs
using var engine = AudioEngineFactory.CreateDefault();
engine.Initialize(AudioConfig.Default);

// List available output devices
var devices = engine.GetOutputDevices();
foreach (var device in devices)
{
    Console.WriteLine($"{device.Name} - {(device.IsDefault ? "Default" : "")}");
}

// Switch to specific device
engine.Stop();
engine.SetOutputDeviceByName("Speakers (Realtek Audio)");
engine.Start();

// Handle device change events
engine.OutputDeviceChanged += (sender, e) =>
{
    Console.WriteLine($"Output device changed: {e.DeviceName}");
};

Recording Audio

Recording.cs
// Enable input in configuration
var config = new AudioConfig
{
    SampleRate = 48000,
    Channels = 2,
    BufferSize = 512,
    EnableInput = true,
    EnableOutput = false
};

using var engine = AudioEngineFactory.Create(config);
engine.Initialize(config);
engine.Start();

// Receive audio samples from input
var buffer = new float[config.BufferSize * config.Channels];
int samplesReceived = engine.Receives(out buffer);

if (samplesReceived > 0)
{
    // Process received audio samples
    ProcessAudioInput(buffer, samplesReceived);
}

engine.Stop();

OwnaudioNET Usage

NET API High-level API with professional features for production-ready applications.
⚠️ IMPORTANT FOR UI APPLICATIONS When building desktop (WPF, WinForms, MAUI, Avalonia) or mobile applications, ALWAYS use the async API methods to prevent UI thread blocking:
  • InitializeAsync() instead of Initialize()
  • StopAsync() instead of Stop()
  • ShutdownAsync() instead of Shutdown()
This prevents your application from freezing during audio initialization (50-5000ms) and shutdown (up to 2 seconds).

Basic Playback (Console Applications)

BasicPlayback.cs
using OwnaudioNET;
using OwnaudioNET.Sources;

// Initialize OwnaudioNET (synchronous - OK for console apps)
OwnaudioNet.Initialize();

// Create file source
var source = new FileSource("music.mp3");

// Create mixer and add source
var mixer = new AudioMixer(OwnaudioNet.Engine);
mixer.AddSource(source);
mixer.Start();

// Play the source
source.Play();

// Wait for playback to finish
while (!source.IsEndOfStream)
{
    Thread.Sleep(100);
}

// Clean up
mixer.Stop();
mixer.Dispose();
source.Dispose();
OwnaudioNet.Shutdown();

UI Application Playback (WPF/MAUI/Avalonia) ⭐ RECOMMENDED

UIApplication.cs
using OwnaudioNET;
using OwnaudioNET.Sources;

public class AudioPlayerViewModel
{
    private AudioMixer? _mixer;
    private FileSource? _source;

    // Initialize asynchronously (UI remains responsive!)
    public async Task InitializeAsync()
    {
        // ✅ Async initialization prevents UI freezing
        await OwnaudioNet.InitializeAsync();

        _mixer = new AudioMixer(OwnaudioNet.Engine);
        _mixer.Start();
    }

    // Play audio file
    public void Play(string filePath)
    {
        _source?.Dispose();
        _source = new FileSource(filePath);

        _mixer?.AddSource(_source);
        _source.Play();
    }

    // Stop playback
    public void Stop()
    {
        _source?.Stop();
    }

    // Shutdown asynchronously (UI remains responsive!)
    public async Task ShutdownAsync()
    {
        _source?.Dispose();

        _mixer?.Stop();
        _mixer?.Dispose();

        // ✅ Async shutdown prevents UI freezing
        await OwnaudioNet.ShutdownAsync();
    }
}

// Usage in UI event handler (e.g., WPF Button Click)
private async void InitButton_Click(object sender, RoutedEventArgs e)
{
    InitButton.IsEnabled = false;
    StatusText.Text = "Initializing audio...";

    try
    {
        await _audioPlayer.InitializeAsync(); // UI stays responsive!
        StatusText.Text = "Audio system ready!";
        PlayButton.IsEnabled = true;
    }
    catch (Exception ex)
    {
        StatusText.Text = $"Error: {ex.Message}";
    }
    finally
    {
        InitButton.IsEnabled = true;
    }
}

Volume Control and Seeking

VolumeControl.cs
var source = new FileSource("music.mp3");

// Volume control (0.0 - 1.0)
source.Volume = 0.8f;

// Seek to position (in seconds)
source.Seek(30.0);

// Loop playback
source.Loop = true;

// Check playback state
if (source.State == AudioState.Playing)
{
    Console.WriteLine($"Position: {source.Position:F2}s / {source.Duration:F2}s");
}

Multiple Sources (Multi-Track)

MultiTrack.cs
OwnaudioNet.Initialize();

var mixer = new AudioMixer(OwnaudioNet.Engine);
mixer.Start();

// Add multiple sources
var drums = new FileSource("drums.wav");
var bass = new FileSource("bass.wav");
var guitar = new FileSource("guitar.wav");

mixer.AddSource(drums);
mixer.AddSource(bass);
mixer.AddSource(guitar);

// Control individual volumes
drums.Volume = 0.8f;
bass.Volume = 0.7f;
guitar.Volume = 0.6f;

// Play all sources
drums.Play();
bass.Play();
guitar.Play();

// Master volume control
mixer.MasterVolume = 0.9f;

Synchronized Playback (Master Clock)

SyncPlayback.cs - New Master Clock API (v2.1.0+)
var drums = new FileSource("drums.wav");
var bass = new FileSource("bass.wav");
var guitar = new FileSource("guitar.wav");

mixer.AddSource(drums);
mixer.AddSource(bass);
mixer.AddSource(guitar);

// Attach sources to Master Clock for sample-accurate sync
drums.AttachToClock(mixer.MasterClock);
bass.AttachToClock(mixer.MasterClock);
guitar.AttachToClock(mixer.MasterClock);

// Optional: Set start offsets on timeline
guitar.StartOffset = 2.0;  // Guitar starts 2 seconds later

// Start mixer
mixer.Start();

// Start all sources for playback
drums.Play();
bass.Play();
guitar.Play();

// All sources now play in perfect sync with Master Clock

// Timeline control
mixer.MasterClock.SeekTo(10.0);  // Seek all tracks to 10 seconds
Master Clock Benefits The new timeline-based system provides sample-accurate synchronization, start offsets for DAW-style track positioning, automatic drift correction (<10ms tolerance), and realtime/offline rendering modes.

Audio Effects

Effects.cs
using OwnaudioNET.Effects;

var source = new FileSource("guitar.wav");

// Create effects
var reverb = new ReverbEffect
{
    Mix = 0.3f,
    RoomSize = 0.7f,
    Damping = 0.5f
};

var compressor = new CompressorEffect(
    threshold: 0.5f,       // 0.5 = -6dB threshold
    ratio: 4.0f,
    attackTime: 10.0f,
    releaseTime: 100.0f,
    sampleRate: 48000f
);

// Apply effects to source
var sourceWithEffects = new SourceWithEffects(source, reverb, compressor);

mixer.AddSource(sourceWithEffects);
sourceWithEffects.Play();

// Master effects (applied to final mix)
var limiter = new LimiterEffect(sampleRate: 48000f, threshold: -0.5f);
mixer.AddMasterEffect(limiter);

Tempo and Pitch Control

TempoAndPitch.cs
var source = new FileSource("vocal.wav");

// Change tempo (speed) without affecting pitch
source.Tempo = 1.2f;  // 20% faster

// Change pitch without affecting tempo
source.PitchShift = -2.0f;  // 2 semitones lower

// Both can be used together
source.Tempo = 0.9f;      // 10% slower
source.PitchShift = 3.0f;  // 3 semitones higher

Recording

Recording.cs
var config = new AudioConfig
{
    SampleRate = 48000,
    Channels = 2,
    BufferSize = 512
};

OwnaudioNet.Initialize(config);

var mixer = new AudioMixer(OwnaudioNet.Engine);
mixer.Start();

// Start recording output to file
mixer.StartRecording("output.wav");

// ... play sources ...

// Stop recording
mixer.StopRecording();

Platform-Specific Setup

No Setup Required! Ownaudio automatically detects your platform and uses the appropriate native audio API.

Supported Platforms

Windows

WASAPI - Windows Audio Session API for low-latency audio

macOS

Core Audio - Native macOS audio framework

Linux

PulseAudio - Standard Linux audio server

iOS

Core Audio - Native iOS audio framework

Android

AAudio - Modern Android audio API

Platform Detection

PlatformInfo.cs
// Get platform information
string platformInfo = AudioEngineFactory.GetPlatformInfo();
Console.WriteLine($"Platform: {platformInfo}");

// Output examples:
// "Windows-WASAPI"
// "macOS-CoreAudio"
// "Linux-PulseAudio"
// "iOS-CoreAudio"
// "Android-AAudio"

Next Steps

📚 CORE API Reference

Low-level cross-platform audio engine.

View CORE Docs →

📚 NET API Reference

High-level audio API with professional features.

View NET Docs →

🎛️ Examples

Discover all available audio effects and how to use them effectively.

Browse example →