Thursday, June 13, 2019

python - How to create old-school format music with small file sizes


My friend and I have been working on a project recently, and because we are hard coding everything (other than the graphics library, Pygame), the total size for our project is super small. I feel like this is awesome and because the game has a retro feel to it I thought it was fitting. The whole project including art is about half a megabyte, which is pretty good when factoring the art and level design and such.


However one thing that is not accounted for in this size is the music. The music itself (around 6 or so tracks) plus the sound effects (4 or 5 currently) make up about 99% of the file size (not an exaggeration, 60mb / 60.5mb is a little over 99%), which I find a little ridiculous. In the old days when games had ridiculously lower memory and file sizes, how did they pull off music? Our game uses Chiptune music to give it a more retro feel, so using that style of music for small file sizes is perfectly acceptable.


Also I because I'm using Python and PyGame I don't know if this will be possible, but I still would like to know the process used anyways so maybe I can play around with it.



Answer




As for your implied question of how do I reduce the file sizes of music, you have these options:


Better compression


60MB for 6 music tracks and 4 or 5 sound effects is too big. I'm guessing you either have really long tracks, or they are very high quality and/or lightly compressed, but usually there is no reason to do so:




  • Unless you are catering to audiophiles or are making a music game, most people won't care about the sound quality. High quality audio tends to be limited to games distributed over physical media where they can afford the extra size, or is a "HD" game where everything needs to be high quality. Since you're worrying about file size, I'm guessing that's not you.




  • In a game, most people would be focused on the game and not the music, and won't notice if the latter is low quality.





Here are some general tips:



  • Use a modern format like Ogg Vorbis, produced with a modern encoder. These have come a long way since those early MP3s encoded with crappy CBR encoders, achieving the same quality at a fraction of the bitrate (and hence file size).

  • Use a low bitrate. Most music is produced for listening alone, but since you're putting it in a game, quality is hard to notice. Don't be afraid to go very low with the bitrate, say 60-96kbps, as modern formats/codecs hold up quite well. YMMV so encode and listen for yourself.

  • Have short tracks. Compared to most popular music which tends to be 3-5 minutes per track, game music tracks are much shorter, partly because the player usually doesn't notice. If you look at the OST for Oblivion for example, its tracks are only 2 minutes average. Skyrim has longer tracks, but there are still plenty of 2-minute tracks. Most other games have shorter tracks. IMO 1 minute is a good length, as it's long enough for the composer to have room for expression and for the player to not notice the repeating.


With these tricks you can get down to ~2MB per track.


Tracker music


As this answer mentions, for a period of time most music used tracker formats, which is a special file that contains a number of samples and the instructions on how to play those, at various times and pitches. Most such music was hardware-specific; they'd use the hardware's built-in sample bank as instruments, so the "music file" was analogous to sheet music alone. For example, most consoles prior to the 5th generation had special music chips which contained the sample banks, so all music for the same console tended to sound similar.



For modern PCs however, you need to provide your own sample bank. Still, these files were much smaller than if the music were a single encoded-PCM file. A typical 4MB MP3 would be about 200kB if it were tracker music. pygame.mixer.music fully supports many tracker formats via libmodplug. The downside is obviously you are greatly limited to a fixed sample bank and you can't do much post-processing.


For examples, Mod Archive contains many outstanding tracks including those by skaven who notably provided tracker music for Unreal Tournament and Bejeweled. Do note that most of the tracks on Mod Archive are not freely derivable, including in your game, so you will need to seek permission or look elsewhere.


There are many music trackers you can use to make tracker music, some free, and each has its own dedicated following owing to their diverse heritages.


MIDI music


Perhaps the smallest option you can use is to have MIDI files as music, which is, like tracker music, a format that specifies how instruments are played. Since it's a standard format and not hardware-specific, it relies on your computer's MIDI sound module, which IMHO tends to sound crap most of the time. Still it must have a niche appeal; Doom's music was MIDI after all.


pygame fully supports playing MIDI files; see this SO question.


Depending on the complexity of the track, a typical MIDI composition will be about 50-100kB in size.


There are also many programs you can use to create MIDI music; a lot of music software exports to MIDI since it's a standard exchange format.


Of course that's not all the ways you can have very small music; you can hit the sound driver directly and synthesise your music, which is likely how a lot of the restricted-size "compos" did it, but it's something you do for its own sake rather than to save on file size.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...