[Solved] Music playback with cross platform in mind.

There are several methods of getting background music into Monogame, but unless I’m mistaken, each method seems to have a serious flaw.

Using Song - Very easy to use, but there’s a very noticeable gap in the playback if you’re looping music. This is related to streaming and there doesn’t seem to be any way around it.

Using SoundEffect - Looping works great. The downside: all your music gets spit out the pipeline as giant wave files. Not a big deal for a PC but this is fatal for a mobile project. These music assets really need to ship in a compressed format.
Is there any way to run the content importer on an mp3 or ogg file at run time? Or some other way to load a sound effect from an mp3 or ogg file at run time?

Using XACT - This appears to be the preferred method from a cursory google search but leaves alot of questions. The tool is not part of monogame and doesn’t seem to be hosted by Microsoft anywhere anymore. I can’t actually find the tool. XACT still only uses WAV files right? How much compression am I actually going to get from it? Its also not clear what parts of XACT are actually supported and information is very sparse. Would it be weird to have an XACT project for each song so that I don’t have to load all the music at once? Is anyone here using XACT?

Third Party Libraries - FMOD seems highly regarded. Their license page is very vague for something I want to sell on the app store: https://www.fmod.com/licensing. Open source solutions exist, like SimpleAudioPlayer but has the same streaming gap as Song.

Does anyone else have suggestions or experience on this topic?

1 Like

I discovered a couple of interesting things:

First, for Song, the gap in sound seems related to the MediaStateChanged event and looping directly. I noticed that if I began a new song, the playback would be instant. This seems to mean that the Windows code that MediaPlayer relies on has a hardcoded delay for its completed event. This delay seems to be 100ms.

By keeping track of how far into the song I’ve gone, I can overcome the gap by just calling Play again when the duration has ended.

But I’ve found a new problem. The Android MediaPlayer begins playback roughly a second and a half into a Song! Which is kind of a bummer, maybe I can find a way to overcome this as well.

I haven’t tested on iOS yet

Feel free to open issues on GitHub for the bugs you’re running into. Make sure you search the existing ones first though, I’m pretty sure there’s an open issue for the looping not being seamless.

For the Android issue, it’s possible that the delay in starting is caused by both preparing and playing the song in the wrapper’s play method. it might be fixed if prepare were called ahead of time. I’ll continue to experiment on that

I think I’ve seen the open looping issue, I know there’s other threads about this. I’ll consolidate my findings and then see what issues are open.

1 Like

Sorry to keep updating my own thread but I found some more interesting information.

For Android, monogame just wraps Song around an Android Media Player. I created one in my Activity and it worked just fine. It spun up instantly and didn’t skip ahead. Just like the windows media player, there’s a loop delay that I can overcome by tracking the duration myself and setting the play position back to zero.

If I stitched two songs together (I have an intro music file and a looping music file), they can be sewn together seamlessly if each song has its own Android MediaPlayer. There is a very tiny gap if you reuse the same one.

So if Monogame just uses an Android Media Player, why is it performing so poorly? The answer seems to be in the format it wants to use. If I loaded an mp3 or ogg, it was great. But Monogame wants to export Android songs in an AAC format (mp4 according to comments in the code). If I used THAT format, my Android Media Player starts late and not at the beginning, just like the Monogame song.

Armed with this information, I think I can write my own “Song” engine that works around all the issues. These aren’t bugs in directly in monogame, just various issues with the stuff that monogame relies on for audio playback.

1 Like

Based on that MonoGame should definitely change the format it exports for Android songs. Could you open an issue for that?

Done

I will update this thread when new information is available

Well, I thought I could overcome the gap by tracking time, but turns out I really didn’t. It still shows up sometimes.

I have solved my problem by converting Ogg files to wav on the fly into a buffer folder while the game is running. You can do this with NAudio and Vorbis. Small APK with perfect music intros/looping:)

I appreciate now how big a deal audio programming really is. Virtually every platform’s standard mediaplayback library (which Monogame relies on for streaming audio) has the loop gap (you can find TONS of threads about it on android dev forums). I guess this is why FMOD is highly regarded. Everyone wants a perfect sound engine from monogame, but few really understand what an undertaking that would be.

I’ve learned alot about Monogame from this and now have a stronger appreciation for it. Once my game is complete, I hope to make some contributions.

2 Likes

Thanks, that’s great :slight_smile: