MonoStereo 1.3.0

dotnet add package MonoStereo --version 1.3.0                
NuGet\Install-Package MonoStereo -Version 1.3.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MonoStereo" Version="1.3.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add MonoStereo --version 1.3.0                
#r "nuget: MonoStereo, 1.3.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install MonoStereo as a Cake Addin
#addin nuget:?package=MonoStereo&version=1.3.0

// Install MonoStereo as a Cake Tool
#tool nuget:?package=MonoStereo&version=1.3.0                

MonoStereo

Icon

nuget

MonoStereo is an audio engine built for MonoGame using the NAudio audio framework.

MonoGame's included audio support is lackluster, leaving many users to find audio implementation through other projects like FMOD. MonoStereo aims to be a free, open-source, entirely C# native audio engine, built specifically for MonoGame.

With included support for the Content Pipeline, dynamic filter application, multi-threaded safety, and the ability to supply your own custom audio sources/filters where MonoStereo's provided implementations don't meet your needs, you'll have everything you need to make your game's audio stand out above the rest.

Features

  • Entirely C# native
  • Cross platform
  • MonoGame Content Pipeline integration
  • Default audio looping support from audio metadata with LOOPSTART and LOOPEND/LOOPLENGTH tags
  • Dynamic audio filtering with 7 built-in filters
  • Custom audio source support
  • Direct PCM sample access
  • Support for changing audio output device

Installation

MonoStereo is available as a package on Nuget. To install, simply add it as a package reference through your project's package manager.

To use MonoStereo's Pipeline integration, you'll need to add a reference to a built MonoStereo.dll. The easiest way to go about this is to build your project once after MonoStereo has been installed - a compiled MonoStereo.dll should appear in your project's output directory. Reference this file and you should be able to use MonoStereo's custom audio importers and processors.

Usage/Examples

Setup

To begin using MonoStereo, first initialize the audio engine in your game's startup code. This can be done anywhere, but it's recommended to place inside of your Game's Initialize() method.

Use the AudioManager.Initialize() method to start the audio engine. You should supply this method with a Func<bool> that lets the audio engine know when to shut down, as it runs on a separate thread to improve performance.

protected override void Initialize()
{
    base.Initialize();

    // Your other initialization code here

    // `isRunning` will be false when the game stops.
    AudioManager.Initialize(() => !isRunning);
}

You also have access to a few extra variables on startup, namely latency, masterVolume, musicVolume, and soundEffectVolume.

  • latency is the desired latency, in milliseconds, before audio reaches the output device. Increasing this can create a slight delay in audio playback, but helps to reduce choppy audio when lots of post-processing effects are applied. The default 150ms is typically fine, but you may find yourself increasing or decreasing this value depending on your use-case.
  • masterVolume, musicVolume, and soundEffectVolume are pretty self explanatory. These values should be floats that range from 0-1, with 1 being max volume, and 0 being mute. If you want to change the music, sound, or master volumes later, they are available with the properties AudioManager.MasterVolume, AudioManager.MusicVolume, and AudioManager.SoundEffectVolume.

Playback

Before playing audio, you'll want to compile your sources to the correct MonoStereo format. Although this isn't required, it is the only method that is supported by default in MonoStereo. Having a standardized format for both songs and sound effects drastically helps to improve performance in practice.

First, add a reference to MonoStereo.dll in your Content.mgcb file (or whichever pipeline file you want to use). If you need access to this .dll, simply build your game once after adding MonoStereo as a project, and it should appear in your output folder. From there, choose the MonoStereo Audio Importer for all audio you want to compile, and the corresponding song or sound effect processor, depending on how you plan to use the audio.

After compiling, playing audio with MonoStereo is very simple. To play a song, use the following:

Song song = new Song("path/to/song");
song.Play();

Your song path should be the path to the .xnb file generated by the content pipeline, without .xnb at the end.

When playing sound effects, you have 2 options. For sounds that won't be played back very frequently, you can create and play them the same way you would with a song.

SoundEffect sound = new SoundEffect("path/to/sound");
sound.Play();

Alternatively, if a sound is going to be played back frequently, it may be better to cache the sound's data in memory for quicker and more efficient access.

CachedSoundEffect cachedSound = new CachedSoundEffect("path/to/sound");

Now that the sound is cached in memory, you can play it one of two ways:

// Option 1
cachedSound.PlayInstance();

// Option 2
SoundEffect sound = cachedSound.GetInstance(); // Alternatively: new SoundEffect(cachedSound);
sound.Play();

When you no longer need the cached sound effect, call cachedSound.Dispose() to dispose the object.

For both songs and sounds, you have access to the Song and SoundEffect instances that control playback for these objects. Looping support is integrated by default - just change the IsLooped property. Additionally, you can call Pause(), Resume(), and Stop() to control the playback state.

Filters

Adding filters to your audio with MonoStereo is very easy. All you need to do is create a new filter instance, and add it to your audio with the AddFilter() method.

Song song = new("path/to/song");
song.Play();

// Whenever you want to add the filter...
PitchShiftFilter filter = new PitchShiftFilter(pitch);
song.AddFilter(filter);

// Whenever you want to remove the filter...
song.RemoveFilter(filter);

MonoStereo contains 7 built-in filters available to use:

  • HighPassFilter
  • LowPassFilter
  • PanFilter
  • PitchShiftFilter
  • PositionFilter
  • SpeedChangeFilter
  • VolumeFilter Additionally, filter instances are shareable across multiple audio instances. If you create one instance of a PitchShiftFilter, it can be applied to multiple audio sources (songs and sounds alike), and even be applied to the same source multiple times. Changing a property of the filter will carry that change over to every other audio source using the same filter.
SpeedChangeFilter speed = new(0.5f);

song1.AddFilter(speed);
song2.AddFilter(speed);

speed.Speed = 0.4f;
// Applies to both song1 and song2

If you want to apply a filter to every instance of a song or sound, rather than individually applying it to each one, apply it to the respective mixer:

AudioManager.MusicMixer.AddFilter(filter);
AudioManager.SoundMixer.AddFilter(filter);
AudioManager.MasterMixer.AddFilter(filter);

Note: since filters are reference types, in order to remove them, you will need to keep track of your filter's object instance.

Custom Implementations

MonoStereo supports custom implementations for songs, sounds, and filters. To use them, you can have classes inherit from ISongSource, ISoundEffectSource, and AudioFilter. You will need to provide a couple methods for each, and some more customization is optionally available through virtual overrides. For filters, you can override ModifyRead() to change the way that reading of the underlying source is handled, or PostProcess() to apply effects to audio after it has been read into memory.

To use the custom sources:

Song song = new Song(new MyCustomSongSource());
SoundEffect sound = new SoundEffect(new MyCustomSoundEffectSource());

song.AddFilter(new MyCustomAudioFilter());

Audio reading is done through 32-bit IEEE floating-point samples. In order to implement any of the above classes, you'll need to supply a method that works with these samples. If you are unfamiliar with the inner-workings of audio reading, it is recommended to stick with MonoStereo's supplied implementations - but if you would like to learn, NAudio has some great references to study from.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.0 38 9/26/2024
1.2.8 109 9/15/2024
1.2.7 90 9/15/2024
1.2.6 69 9/13/2024
1.2.5 92 9/6/2024
1.2.4 86 9/4/2024
1.2.3 87 9/4/2024
1.2.2 91 9/1/2024
1.2.1 81 9/1/2024
1.2.0 99 9/1/2024
1.1.9 87 9/1/2024
1.1.8 78 9/1/2024
1.1.7 73 9/1/2024
1.1.6 82 9/1/2024