AudioMixer

The central mixing engine. Combines multiple audio sources, applies master effects, and drives audio output. Namespace: OwnaudioNET.Mixing

Constructor

C#
// bufferSizeInFrames: use 1024 for complex multi-track setups
var mixer = new AudioMixer(OwnaudioNet.Engine!.UnderlyingEngine, bufferSizeInFrames: 512);
ParameterTypeDefaultDescription
engineIAudioEngine—From OwnaudioNet.Engine.UnderlyingEngine.
bufferSizeInFramesint512Internal mix buffer. Use 1024 for 20+ tracks.

Properties

PropertyTypeDescription
MixerIdGuidUnique identifier.
ConfigAudioConfigAudio configuration in use.
IsRunningboolWhether the mix thread is active.
SourceCountintNumber of active sources.
MasterVolumefloatMaster output volume (0.0 – 1.0). Settable at any time.
LeftPeak / RightPeakfloatReal-time peak levels (0.0 – 1.0) for VU metering.
TotalMixedFrameslongTotal frames processed since last Start().
TotalUnderrunslongTotal buffer underruns since last Start().
IsRecordingboolWhether WAV recording is active.
MasterClockMasterClockTimeline clock for synchronized multi-track sync.
RenderingModeClockModeRealtime (default) or Offline.

Lifecycle

C#
mixer.Start();                      // begin audio processing
mixer.Pause();                      // freeze mix thread
mixer.Stop();                       // stop and clear all sources
mixer.Seek(double positionInSec);   // seek master clock + all attached sources
mixer.Dispose();                    // release all resources

Source Management

C#
// Add and immediately start
mixer.AddSource(source);

// Add without starting — launch all at once for tight sync
mixer.AddSourcePrepared(vocals);
mixer.AddSourcePrepared(backing);
mixer.StartPreparedSources(startPosition: 0.0); // atomic start

// Remove
mixer.RemoveSource(source);          // by reference
mixer.RemoveSource(sourceGuid);      // by ID
mixer.ClearSources();                // remove + stop all

// Query
IAudioSource[] all = mixer.GetSources();
â„šī¸

AddSource() and RemoveSource() are lock-free hot-swap operations — safe to call while the mixer is running.

Maximum simultaneous sources per mixer: AudioConstants.MaxAudioSources = 25

Master Effects

Effects applied to the final mixed signal in the order they are added. See Effects for the full effect list.

C#
// Add effects in chain order
mixer.AddMasterEffect(new CompressorEffect { Ratio = 4f });
mixer.AddMasterEffect(new ReverbEffect { RoomSize = 0.5f, Mix = 0.2f });
mixer.AddMasterEffect(new LimiterEffect());

// Manage
mixer.RemoveMasterEffect(effect);   // returns bool
mixer.ClearMasterEffects();
IEffectProcessor[] fx = mixer.GetMasterEffects();
âš ī¸

The effect must have IsReady == true before adding. For VST3 effects, call await host.InitializeAudioAsync() first.

Recording

Records the final mixed output — post master-effects — to a WAV file.

C#
mixer.StartRecording("session.wav"); // start capturing
// ... playback ...
mixer.StopRecording();               // finalize and close the WAV file

VU Metering

C#
// Update at ~10Hz (100ms timer)
_vuTimer = new Timer(_ =>
{
    // Master bus
    float leftDb  = 20f * MathF.Log10(Math.Max(mixer.LeftPeak,  1e-6f));
    float rightDb = 20f * MathF.Log10(Math.Max(mixer.RightPeak, 1e-6f));
    MasterLeftDb  = Math.Max(leftDb,  -60f);
    MasterRightDb = Math.Max(rightDb, -60f);

    // Per-track (if source is BaseAudioSource)
    var (l, r) = source.OutputLevels;
    TrackLeftDb = 20f * MathF.Log10(Math.Max(l, 1e-6f));
}, null, 0, 100);

Events

EventArgsDescription
PlaybackEndedEventArgsAll sources reached EndOfStream.
BufferUnderrunBufferUnderrunEventArgsMix thread couldn't fill buffer in time.
SourceErrorAudioErrorEventArgsAn error occurred in one of the sources.
TrackDropoutTrackDropoutEventArgsA source missed its master clock deadline.
C#
mixer.PlaybackEnded += (_, _) =>
{
    // All tracks finished — update UI state
};

mixer.BufferUnderrun += (_, e) =>
{
    Console.WriteLine($"Underrun: {e.MissedFrames} frames at position {e.Position}");
};

mixer.TrackDropout += (_, e) =>
{
    Console.WriteLine($"Dropout on {e.TrackName}: {e.Reason} ({e.MissedFrames} frames)");
};