Master volume for sound effects and songs?

Alright. So here’s the thing. I’m trying to code a modular engine ontop of MonoGame - called the Peace engine, for my game, The Peacenet. You can find general information on the engine here, and I plan to release it as a standalone engine eventually.

One of the things I want to allow in the Peace engine is an easy way to have a master volume set for background music and sound effects. An already-existing example of this would be in most AAA games, where in their settings menu, they usually have a volume setting for sound effects, and a volume setting for music - or how in Windows you can set, for example, Chrome to 50% volume while your master system volume is at 100%, and lowering the system volume reduces Chrome’s proportionally so it’s always half as loud as the master volume.

The game can then play sound effects at an arbitrary volume, proportional to the master volume set in the engine settings. So, theoretically, I’d get a sound effect object from the engine, and it would have the usual properties - pitch, volume, etc and the usual methods - play, pause, stop, you name it. In the game, I could set the sound effect’s volume to 100%, and the engine would treat that value as a proportional value to the master volume. So, if I have a master volume of 50%, and the sound effect’s volume property is 50%, in reality, it should be played at 25% volume - because 50% of the master volume is 25. 0.5 * 0.5 = 0.25.

So, mathematically, and theoretically, this is perfectly possible and has obviously been done before in engines like RAGE (Rockstar’s proprietary engine used for GTA 4, GTA 5, and other games), and even most modern operating systems.

My question is, is this possible in MonoGame, and how would it be done with the least amount of spaghettification (awkward code that’s hard to read and work with, hacks, things that work but don’t work very well, things like that), and how can I conceal it within the engine’s code so the user doesn’t have to deal with it beyond knowing that it is in fact happening?

And an even harder question is, given that Songs are played in a static MediaPlayer class, can Song objects even HAVE proportional volumes like this? Would audio fades even be possible without adjusting the engine’s master volume?

For SoundEffects check out SoundEffect.MasterVolume:

Each SoundEffectInstance has its own Volume property that is independent to SoundEffect.MasterVolume. During playback SoundEffectInstance.Volume is multiplied by SoundEffect.MasterVolume.

It also affects sound effect instances that are playing.

I’m not sure about songs. I think it would be possible using XACT. With the Song API it’s not possible to play multiple songs at once. (the difference between Song and SoundEffect is that SoundEffects are loaded into memory, while Songs are streamed from disk, so you could load your game music as SoundEffects if they’re not too large).