[Dev] [Audio] Audio Thread

Quintillus

Archiving Civ3 Content
Moderator
Supporter
Joined
Mar 17, 2007
Messages
8,411
Location
Ohio
It looks like Audio doesn't currently belong to any milestone. As it was, I'd been wanting to try out Godot 3.3's shiny new mp3 support since I read about it, and I'm happy to say that the Main Menu will now play any mp3 file located in <civ install path>/Sounds/Menu/Menu1.mp3

Happily, as far as I can tell, that really is any mp3, not the 128 kbps only (and maybe other limitations) that Civ III allows. I've moved an mp3 of a variable bit rate mp3 version of Baba Yetu over to that file location, and C7 is happily playing it, while Civ III crashes if I try to launch it with a variable-bit-rate mp3.

Since you might not fancy hearing the main menu music every time, I've left it off by default; there's a boolean in MainMenuMusicPlayer.cs (at the top level of Prototype) that you can toggle to hear the music.

There's just a little bit of ceremony in getting the mp3s to play, which you can also see in the file. It probably makes sense to add a utility method like we have for PCXs, so going forward we can have super simple setup for playing audio.

Now I'm tempted to add the ambiance mp3s as well... although as WAV files, it appears that they aren't quite as out-of-the-box straightforward as mp3s when loaded in code rather than as bundled resources.
 
I went down the WAV rabbit hole a bit. Learned some useful things for implementing it, including some good references. I'll add my notes here so I can find them later, as well as in case anyone else has ever wondered what a WAV file is composed of.

Spoiler Lots of WAV details :
Wikipedia does a pretty good job of describing the format, better than for many image formats, and also links to contemporary documentation on the format published by IBM and Microsoft in 1991. At a high level, a WAV file starts out with 8 bytes that are the type of container format it is (RIFF), and the file size, minus 8 bytes. It then identifies itself (WAVE), and then has two or more data chunks.

One of these chunks is the "fmt " chunk. This tells you the format of the audio, such as sample rate, whether it's 8-bit or 16-bit, etc. It must be before the "data" chunk, which is the actual audio data.

There can also be other chunks, such as the "smpl" (sample) chunk, which gives information about loop points, and the "junk" chunk, which Microsoft and IBM helpfully so you can store random junk in your WAV file. Or as they put it, "It contains no relevant data; it is a space filler of arbitrary size".

Thankfully, the Godot engine can handle the data chunk, just not all the other ones. Also thankfully, all the chunks start out with their chunk ID, and then the size of the chunk, so if you don't know what to do with them, you can skip them easily. All we need to do is handle the "fmt " chunk, passing the appropriate values into Godot as needed, and then give all of the data chunk data to Godot.

There is some discussion on the Godot GitHub about this, both in the link in the previous post, and on this issue. The consensus seems to be it would be nice to have a simple way to import WAVs at runtime, but it hasn't been added yet (except in somebody's Godot fork).

That said, there are some code references for what this would look like, too. Someone in Spain wrote a script to import WAVs in GDScript, and I also found the Godot C++ source for reading WAVs. The Godot C++ is more robust, though it's worth noting it also does a lot of processing we wouldn't need since we can just hand the engine the "data" and it knows what to do with that.


I also looked at one of the Civ WAV files in a hex editor while comparing it to the documentation. Conveniently, if it's representative, the Civ files only have the minimum amount of chunks, which means the GDScript version would work, and also keeps things simple. So, I'll probably write a C# WAV importer over the next day or two, and cross another format off the list we'll need to write converters for.
 
Happy to reuse other people's work where we can, though I'm not exactly sure how that works as compared to Unity's asset packages. (Do we just copy the file or is there some kind of dependency management?) And if there's anything generic like that we need to write, we can consider publishing it as a standalone utility. Godot could use more community resources.
 
Happy to reuse other people's work where we can, though I'm not exactly sure how that works as compared to Unity's asset packages. (Do we just copy the file or is there some kind of dependency management?) And if there's anything generic like that we need to write, we can consider publishing it as a standalone utility. Godot could use more community resources.

I was thinking the same thing, and literally just published a blog post on how to play mp3s from the file system in the C# version of Godot, since I didn't find any great resources on that. I like the idea of publishing utilities as well, and making the mp3 player a bit more streamlined and user friendly is one of the things we'll have to do anyway (right now it's hard-coded to play the file at the Main Menu Music location).

I don't know much about dependency management in Godot yet, or even really in C#. I think C# users NuGet? But how you publish things to make them accessible, no idea. I have figured that out in the Java/Maven world (where it's got enough overhead with validating control of the domain, e.g. com.civfanatics, and signing/encrypting artifacts that it isn't trivial), but haven't in other environments. For the GDScript version I found, it seems like people are starting the repo on GitHub and copying it into their projects, which certainly isn't the most advanced way to do it, but is also how we've handled Blast.
 
Will this Audio System play all sounds or just MP3s?
What I am really wanting to know is concerning Unit Sounds... will there be another sound program for that and any other game sounds?

Glad you guys are moving right along and gaining more insights and progress :thumbsup:
 
C# uses nuget. I think Mono does a `nuget restore` before building. (Or the equivalent of `dotnet restore` in the SDK previously known as dotnetcore.) I think we have the .ini reader as a nuget package, so we've all managed to make that work so far without question.

As for Blast, in my original read-civ-data repo I made a git subproject where you'd run an extra command or two to fetch the subproject. In C7 Prototype I just copied the code to avoid having to have everyone know to do that.

This all very may well have been before I knew how to use nuget, so maybe there is a nuget package we can use for Blast after all. I also think once upon a time I meant to port my partial implementation (enough to work for all Civ3 file decompression) to C#, but there is probably no true advantage to that.

My early thought for media files is to bundle them in PCK archives which Godot will use natively, and we can have the CI/CD pipeline build it. Git is horrible for binary media, so I figured the source files will be in S3 or somewhere. Or maybe just distributed. A torrent seems like overkill, but that could work.

We'll have to figure out the best way to work with unbundled media packages while developing...I kind of think that will be trivial once we see how it works, but I'm not really sure. Not that we *have* to develop with unbundled media, but if we're adding and updating media I figure we'll want to.
 
Will this Audio System play all sounds or just MP3s?
What I am really wanting to know is concerning Unit Sounds... will there be another sound program for that and any other game sounds?

Glad you guys are moving right along and gaining more insights and progress :thumbsup:

We'll definitely support WAV files, since that's used by Civ for units and a lot of other sound effects. I've seen Puppeteer mention AMB files, which I remain ignorant about, so I'll delegate to what he has said about them.

I expect we'll also support using mp3 files for unit sounds, since I don't see a reason not to. I'm guessing Civ must only support WAV, since all the units I'm exploring only use WAV, including recent Delta Strife ones? But since you could just set "myCoolUnitFortify.mp3" in the .ini file, adding support there should in theory be really easy, once we get to the point of playing unit sounds.

Godot also supports Ogg Vorbis, so that's the next most likely candidate for support. Beyond that, feel free to suggest formats that would be helpful, but it would be more difficult.

C# uses nuget. I think Mono does a `nuget restore` before building. (Or the equivalent of `dotnet restore` in the SDK previously known as dotnetcore.) I think we have the .ini reader as a nuget package, so we've all managed to make that work so far without question.

As for Blast, in my original read-civ-data repo I made a git subproject where you'd run an extra command or two to fetch the subproject. In C7 Prototype I just copied the code to avoid having to have everyone know to do that.

This all very may well have been before I knew how to use nuget, so maybe there is a nuget package we can use for Blast after all. I also think once upon a time I meant to port my partial implementation (enough to work for all Civ3 file decompression) to C#, but there is probably no true advantage to that.

My early thought for media files is to bundle them in PCK archives which Godot will use natively, and we can have the CI/CD pipeline build it. Git is horrible for binary media, so I figured the source files will be in S3 or somewhere. Or maybe just distributed. A torrent seems like overkill, but that could work.

We'll have to figure out the best way to work with unbundled media packages while developing...I kind of think that will be trivial once we see how it works, but I'm not really sure. Not that we *have* to develop with unbundled media, but if we're adding and updating media I figure we'll want to.

I see some code that reads "$NugetPath = '/Users/jim/.nuget/packages'" and later "Add-Type -Path ($NugetPath + '/ini-parser/3.4.0/lib/net20/INIFileParser.dll')" in test.ps1 in the ConvertCiv3Media project. But it probably doesn't work on my system without a Jim account. But I haven't really dug into that yet.

I think we'll always have to support on-the-file-system-not-in-PCK media, for mod support if nothing else.

But even for the core resources, we'd have to assemble a collection of media files that we have permission to redistribute before we can bundle them, which means replacements for the Firaxis assets. Long-term, I think it's a good idea to have that replacement set, but it will be challenging in the short term. But it's a great candidate for non-developers contributing (both in the initial curation, and in creating content to fill in any gaps). Do you think we could get Christopher Tin to make some new main menu music for us?
 
I did some really hacky stuff with PowerShell at times. I was using it to avoid having to make another csproj for a test harness. Now I'm either just using Godot or misusing xUnit as a dev test harness. The PowerShell stuff had to go find all the compiled DLLs itself whereas the dotnet/mono compilers put them in your project when you do it right. I'm probably also not making the most of VSCode's IDE-ness.

Professionally I've been more production support and writing quick little projects but troubleshooting larger ones. Personally I'm pretty hack-in-an-editor, switch windows and compile/run. I'm always learning, though. I guess what I'm saying is that I can get stuff done, but my code so far isn't fully idealized team-project organized. And aside from some dabbling with the csc compiler they used to include with earlier .NETs I only really started coding in C# at the start of this year.


For music, this is a game based on history. I'm guessing there should be plenty of public domain historical music out there that should at least serve as a stand-in.

There are also collections of freely obtainable plus royalty-free music for YouTube, Twitch and so forth, although I have no idea if any of it is licensed for redistribution in a game. Itch.io and Godot communities would probably be a good place to check.

I haven't researched into these, just a quick Googling:

https://itch.io/game-assets/free/tag-music
https://itch.io/soundtracks/free
https://godotengine.org/qa/80355/where-to-find-free-to-use-music-and-sound-effects
 
There's a surprising amount of good royalty-free music, but being able to redistribute it in an open source game is a little more tricky, since uploading the original mp3 to Github kind of defeats the purpose of a personal license.

Getting waaay ahead of myself here.... I really like this track for the main menu. It has a similar vibe to the original, and a nice transition around 0:49 if we were to make our own intro video.
 
That was a fun rabbit hole. Earthquake does have a nice main menu sound. It looks like it isn't free, but is a low fixed cost, and within the realm of possibility.

Following Puppeteer's links, I found a nice synthwave album that we could use if we want to go that route. Not sure synthwave and Civ quite mix, but we'll need something for the modern age.

More traditionally, I checked to see if MusOpen had made any updates to their royalty-free music site, and was pleased to see they'd updated their website, making it much easier to browse, search, and filter. I brought up a list of the Civ IV soundtrack (the high point in the series IMO), and while they don't have recordings of everything on it, there is some overlap in the Renaissance/Industrial ages. I expect we could successfully assemble a classical themed soundtrack from there.
 
We'll definitely support WAV files, since that's used by Civ for units and a lot of other sound effects. I've seen Puppeteer mention AMB files, which I remain ignorant about, so I'll delegate to what he has said about them.

I expect we'll also support using mp3 files for unit sounds, since I don't see a reason not to. I'm guessing Civ must only support WAV, since all the units I'm exploring only use WAV, including recent Delta Strife ones? But since you could just set "myCoolUnitFortify.mp3" in the .ini file, adding support there should in theory be really easy, once we get to the point of playing unit sounds.

Godot also supports Ogg Vorbis, so that's the next most likely candidate for support. Beyond that, feel free to suggest formats that would be helpful, but it would be more difficult.

Naturally, .wav is necessary for existing MODs... It might be a good addition to include .mp3 but I believe Ogg Vorbis would be best over all for the Game, smaller size compression with Good Quality.
 
Top Bottom