How To: Audio

MonoGame's audio APIs work as-is in the Avalonia integration. This guide covers SoundEffect, looping via SoundEffectInstance, and graceful degradation when audio hardware is absent.

Reference file: Advanced/SampleGame.Audio.cs


SoundEffect — one-shot playback

Load from the content pipeline

// In LoadContent:
_shootEffect = Content.Load<SoundEffect>("Sounds/shoot");

// In Update — play on trigger:
if (firePressed)
    _shootEffect.Play();

Create from PCM data

You can synthesise or load raw PCM bytes without the content pipeline:

// 44100 Hz, 16-bit, mono
byte[] pcm = GenerateOrLoadPcm();
_beepEffect = new SoundEffect(pcm, 44100, AudioChannels.Mono);

_beepEffect.Play();
// Or with volume, pitch, pan:
_beepEffect.Play(volume: 0.8f, pitch: 0f, pan: 0f);

The Advanced sample generates a 0.12 s, 880 Hz sine-wave beep entirely in software — see GenerateBeepPcm() in SampleGame.Audio.cs.


SoundEffectInstance — looping / controlled playback

_musicEffect   = new SoundEffect(pcm, 44100, AudioChannels.Mono);
_musicInstance = _musicEffect.CreateInstance();
_musicInstance.IsLooped = true;
_musicInstance.Volume   = 0.75f;
_musicInstance.Play();

// Later, to pause and resume:
_musicInstance.Pause();
_musicInstance.Resume();

// Stop and release:
_musicInstance.Stop();
_musicInstance.Dispose();

SoundEffectInstance is the right choice for background music or any sound that needs volume control, looping, or explicit start/stop.


MediaPlayer — streaming audio

MediaPlayer supports streaming playback from an Song loaded via the content pipeline. It is not demonstrated in the sample (which synthesises audio in software), but the API is identical to standalone MonoGame:

Song song = Content.Load<Song>("Music/theme");
MediaPlayer.Play(song);
MediaPlayer.IsRepeating = true;
MediaPlayer.Volume = 0.5f;

Handling headless / no-hardware environments

Audio initialisation throws if no audio device is available (CI machines, headless servers). Wrap initialisation in a try/catch so the game runs silently:

private SoundEffect?         _beepEffect;
private SoundEffectInstance? _musicInstance;

private void InitAudio()
{
    try
    {
        _beepEffect    = new SoundEffect(GenerateBeepPcm(), 44100, AudioChannels.Mono);

        var musicEffect = new SoundEffect(GenerateMusicPcm(), 44100, AudioChannels.Mono);
        _musicInstance  = musicEffect.CreateInstance();
        _musicInstance.IsLooped = true;
        _musicInstance.Play();
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine($"[MyGame] Audio init failed (no hardware?): {ex.Message}");
        // _beepEffect and _musicInstance remain null; all audio calls guard against null.
    }
}

Call InitAudio() from LoadContent(). All subsequent audio calls should null-check before use:

if (firePressed)
    _beepEffect?.Play();

Disposal

Dispose SoundEffectInstance and SoundEffect in the game's Dispose override or in the window's OnClosed handler (via game.Dispose()):

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        _musicInstance?.Stop();
        _musicInstance?.Dispose();
        _beepEffect?.Dispose();
    }
    base.Dispose(disposing);
}

Calling game.Dispose() in OnClosed (as shown in 01 — Minimal Setup) stops the audio thread and disposes all MonoGame resources including audio.

latest ▼