/Velentr.Audio

A simple audio library for Monogame/FNA.

Primary LanguageC#MIT LicenseMIT

Velentr.Audio

A simple audio library for Monogame/FNA.

Installation

There are nuget packages available for Monogame and FNA.

Features

  • Abstracts audio handling into a system that just requires "tags" to manage when sounds are created
  • Independent audio categories for different sounds
  • Playlist system for music
  • Simple and customizable procedural music generation

Example

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Velentr.Audio;
using Velentr.Audio.Categoreies;
using Velentr.Audio.Core.DevEnv;
using Velentr.Audio.Helpers;
using Velentr.Audio.Playlists;
using Velentr.Audio.Procedural;
using Velentr.Audio.Tagging;

namespace Velentr.Input.DevEnv
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;

        private AudioManager manager;

        private string _soundsCategory = "SOUNDS";


        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

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

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            // create an Audio Manager with the SOUNDS category (this could also be done by creating a new AudioManager without the categories parameter and then calling manager.AddCategory() with our categor(y/ies) instead)
            var categories = new List<CategoryLoadInfo>
            {
                new CategoryLoadInfo(_soundsCategory, 1f)
            };
            manager = new AudioManager(categories: categories, maxMusicInstances: 32);

            // Register some music with our audio manager...
            manager.AddMusic("Drums", "Content\\Music\\Drums-of-the-Deep-153-Loop-Full.wav", 0f, false);
            manager.AddMusic("Lord", "Content\\Music\\Lord-of-the-Land-130-Full.wav", 0f, false);
            manager.AddMusic("Master", "Content\\Music\\Master-of-the-Feast-122-Full.wav", 0f, false);
            manager.AddMusic("Liuto", "Content\\Music\\Suonatore-di-Liuto-Full.wav", 0f, false);
            manager.AddMusic("Tales", "Content\\Music\\Teller-of-the-Tales-130-Full.wav", 0f, false);

            // add some sounds for procedural music
            manager.AddProceduralMusicSample("bass_a2", "Content\\Procedural\\bass_a2.wav", 0f, true);
            manager.AddProceduralMusicSample("bass_b2", "Content\\Procedural\\bass_b2.wav", 0f, true);
            manager.AddProceduralMusicSample("bass_c2", "Content\\Procedural\\bass_c2.wav", 0f, true);
            manager.AddProceduralMusicSample("bass_d2", "Content\\Procedural\\bass_d2.wav", 0f, true);
            manager.AddProceduralMusicSample("bass_e2", "Content\\Procedural\\bass_e2.wav", 0f, true);
            manager.AddProceduralMusicSample("bass_f2", "Content\\Procedural\\bass_f2.wav", 0f, true);
            manager.AddProceduralMusicSample("bass_g2", "Content\\Procedural\\bass_g2.wav", 0f, true);

            manager.AddProceduralMusicSample("elecP_A", "Content\\Procedural\\elecP_A.wav", 0f, true);
            manager.AddProceduralMusicSample("elecP_B", "Content\\Procedural\\elecP_B.wav", 0f, true);
            manager.AddProceduralMusicSample("elecP_C", "Content\\Procedural\\elecP_C.wav", 0f, true);
            manager.AddProceduralMusicSample("elecP_D", "Content\\Procedural\\elecP_D.wav", 0f, true);
            manager.AddProceduralMusicSample("elecP_E", "Content\\Procedural\\elecP_E.wav", 0f, true);
            manager.AddProceduralMusicSample("elecP_F", "Content\\Procedural\\elecP_F.wav", 0f, true);
            manager.AddProceduralMusicSample("elecP_G", "Content\\Procedural\\elecP_G.wav", 0f, true);
            
            // register some sounds with our manager. List them as belonging to the SOUNDS category
            var soundCategories = new List<string>() { _soundsCategory };
            manager.AddSound("beep", "Content\\Sounds\\33775__jobro__1-beep-a.wav", soundCategories, 0f, false, new List<string>() { "beep" });
            manager.AddSound("blaster", "Content\\Sounds\\27568__suonho__memorymoon-space-blaster-plays.wav", soundCategories, 0f, false, new List<string>() { "blast" });

            // create some playlists and say what tags should play or pause them...
            var playlist1 = new PlaylistLoadInfo("playlist1", PlaylistType.Normal);
            playlist1.PlaylistValidTags.AddTag("play", TagType.Normal);
            playlist1.PlaylistPauasedTags.AddTag("pause", TagType.Normal);

            var playlist2 = new PlaylistLoadInfo("playlist2", PlaylistType.Normal);
            playlist2.PlaylistValidTags.AddTag("pause", TagType.Normal);
            playlist2.PlaylistPauasedTags.AddTag("play", TagType.Normal);

            var playlist3 = new PlaylistLoadInfo("proceduralPlaylist", PlaylistType.Procedural);
            playlist3.PlaylistValidTags.AddTag("proceduralPlay", TagType.Normal);

            // Add some music tracks to the playlists...
            playlist1.MusicTracks.Add(new PlaylistMusicInfo("Drums", new List<string>() { "normal", "stress" }));
            playlist1.MusicTracks.Add(new PlaylistMusicInfo("Lord", new List<string>() { "normal" }, new List<string>() { "stress" }));
            playlist1.MusicTracks.Add(new PlaylistMusicInfo("Tales", new List<string>() { "normal" }, new List<string>() { "stress" }));

            playlist2.MusicTracks.Add(new PlaylistMusicInfo("Master", new List<string>() { "normal", "stress" }));
            playlist2.MusicTracks.Add(new PlaylistMusicInfo("Liuto", new List<string>() { "normal" }, new List<string>() { "stress" }));

            playlist3.MusicTracks.Add(new PlaylistMusicInfo("ExampleSong", new List<string>() { "normal" }));

            // add the playlists to the Audio Manager...
            manager.AddPlaylist(new List<PlaylistLoadInfo>() { playlist1, playlist2, playlist3 });

            // register the procedural song(s) with the procedural playlist(s)
            manager.AddProceduralSong("proceduralPlaylist", "ExampleSong", new ExampleProceduralSong(manager, 42));

            // Setup some tags for what playlist and music we should play...
            manager.AddPlaylistChoiceTag("proceduralPlay");
            manager.AddMusicTag("normal");
        }

        private TimeSpan _lastBeepSoundTime = TimeSpan.MinValue;
        private TimeSpan _lastBlasterSoundTime = TimeSpan.MinValue;

        protected override void Update(GameTime gameTime)
        {
            // update the manager
            manager.Update(gameTime);

            // every 2.5 seconds, play a beep sound
            if (TimeHelpers.ElapsedMilliSeconds(_lastBeepSoundTime, gameTime) > 2500)
            {
                _lastBeepSoundTime = gameTime.TotalGameTime;
                manager.AddTag(_soundsCategory, "beep", true, 500);
            }

            // every 6 seconds, play a blaster sound
            if (TimeHelpers.ElapsedMilliSeconds(_lastBlasterSoundTime, gameTime) > 6000)
            {
                _lastBlasterSoundTime = gameTime.TotalGameTime;
                manager.AddSoundTag(_soundsCategory, "blast", true, 500);
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}

Future Plans

See list of issues under the Milestones: https://github.com/vonderborch/Velentr.Audio/milestones

License Information

Velentr.Audio

MIT - https://github.com/vonderborch/Velentr.Audio/blob/main/LICENSE

Dev Environment Music

Drums of the Deep Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/

Lord of the Land Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/

Master of the Feast Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/

Suonatore di Liuto Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/

Teller of the Tales Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/

Dev Environment Sounds

MemoryMoon_space-blaster-plays.wav suonho (https://freesound.org/people/suonho/sounds/27568/) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/

tone beep.wav pan14 (https://freesound.org/people/pan14/sounds/263133/) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/