AndrewRussellNet / FNA-Template

A simple template for FNA game projects.
69 stars 8 forks source link

mp3/ogg source files compile to WMA via MGCB #4

Open danielcrenna opened 6 years ago

danielcrenna commented 6 years ago

If this demo included a bxfr sound sample, that would be helpful.

Basically, any source audio pushed through Content.mgcb is output as a Windows WMA file, presumably because MonoGamePlatform is set to Windows. This causes a ContentLoadException without fail, because FNA doesn't support WMA.

Now it may be that the answer is to set mgcb Build Action to "Copy". but then this requires code changes and explicit loading (i.e. cannot use ContentManager). I don't know if there is am FNA-specific ogg importer for mgcb that knows not to generate a WMA file. /cc @flibitijibibo

I'm currently working with existing code, and don't want to change the sources.

danielcrenna commented 6 years ago

This is basically the fix, and it looks like FNA-Template would have to ship with a custom pipeline(s) for audio files. https://github.com/FNA-XNA/FNA/issues/126#issuecomment-385774973

danielcrenna commented 6 years ago

I also attempted creating a new Audio.mgcb, setting the outputDir/intermediateDir/platform on that specific file to DesktopGL, thinking I'd make a custom msbuild step to relocate that output and remove any .WMA files (klugey). But, the only way I can get that file to build proper xnb/ogg pairs is if I run it using the MGCB GUI. The targets file blows past any non-Windows content, likely keyed off MonoGamePlatform in the .csproj file.

Perhaps @LennardF1989 has code to donate for this, but I don't think FNA-Template wants to reference any MonoGame libraries directly.

flibitijibibo commented 6 years ago

ContentManager should be able to read ogg files without any XNB - the XNB just has a Duration value that gets picked up by MediaPlayer anyway. Same idea as FXB, ogv, and common image formats!

danielcrenna commented 6 years ago

In my experience, if I take an OGG file and set it to passthrough / copy in mgcb, the ContentTypeReader guesses it's a .wav file (as that's the only available entry in SoundEffectReader.supportedExtensions, so .ogg is never guessed.

Normally not a problem unless you don't want to change the source code, which is using ContentManager's extensionless convention, like Content.Load<SoundEffect>("bloop")

flibitijibibo commented 6 years ago

Weird, it really forces a conversion and doesn’t let you copy? Guess that’d have to go in the csproj instead then... if you can reference content files outside the root tree. (Is that easy with msbuild? Would like to have that for Xbone builds)

danielcrenna commented 6 years ago

It copies, but fails at runtime when referencing by assetName without an extension.

flibitijibibo commented 6 years ago

It does...? It shouldn’t:

https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentManager.cs#L308

danielcrenna commented 6 years ago

I think I made a mistake in that specific case where I’m trying to load an .ogg file as a SoundEffect (vs a Song) via Load which can only be a .wav.

FNA-Template works with wav files, it’s indeed the Song mp3/ogg files that are forced to WMA if passed through the mgcb. I guess I need to convert sound effects to wav, songs to ogg, and set them all to pass through.

On Jun 22, 2018, at 12:53 AM, Ethan Lee notifications@github.com wrote:

It does...? It shouldn’t:

https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentManager.cs#L308

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

LennardF1989 commented 6 years ago

Hello @danielcrenna - In order to force MGCB to always spit out OGG files, regardless of platforms, you need to do some hackery. More specifically, you have to force DesktopGL in the instance of Songs. For the greater good, I'm more than willing to donate this piece of code:

https://gist.github.com/LennardF1989/a5d7d54c89cb6cd0e6bc9551b6fa6a48

Register the DLL containing this class in your Content-project, and set all songs to "Ogg Song - MonoGame". That's it!

As the TODO mentions, there is currently a slight problem: Ogg-files do not seem to be deterministic. Given the exact same input, different outputs are produced every time. The idea here is to persist the content of SongContent to the file-system along with the SHA1-hash of the incoming song. It's on my road-map to sort this out as it just inflates patches if you forget about it.

flibitijibibo commented 6 years ago

I believe the reason encodes aren't always the same is because the Ogg stream serial isn't always the same. When using oggenc you have to use -s to set a specific serial and then it should be consistent; MGCB uses ffmpeg so I'm not sure what the flag is to set the stream serial number.