Design a site like this with WordPress.com
Get started

The tale of clownaudio – Part 3

Okay, where was I…

So I had a basic music player, which would decode Ogg Vorbis data using libvorbis and play it to the user with Cubeb. For the basic purpose of adding Ogg Vorbis support to a game that originally lacked it, this was good enough.

Or… so I thought. With the release of my Ogg Vorbis mod, I was no longer the only one testing clownaudio. Eventually, I received a bug report that it didn’t work on Windows XP.

Windows XP compatibility

Now I know some of you will roll your eyes at the thought of supporting such an outdated OS, but the nerd in me wasn’t content with making a mod that was less portable than the game it was based on. Besides, it’s just a glorified music player – why couldn’t it work on Windows XP?

Well, it turned out that the problem was Cubeb: unlike SDL2, it only supports Windows Vista(?) and above. Great. I’d spent all this time migrating clownaudio from SDL2 to Cubeb, only to find that it ruined backwards-compatibility.

That said, I didn’t want to just rip out my Cubeb code and plug the old SDL2 code back in. No… SDL2 is big and bloated and old and gross, while Cubeb is new and shiny and cool. So, I decided to just support both:

To achieve this, I refactored clownaudio so that the Cubeb code was entirely decoupled from the rest of the engine, allowing it to be kept in its own source file. I could then create another source file that exposes the same API as the Cubeb one, except it implements it using SDL2 instead. Then, at compile-time, I could simply choose which ‘backend’ I want, and the produced DLL would use the appropriate library for audio playback. That way I didn’t have to give up Windows XP compatibility or using a cool new library.

And so my mod started to provide two DLLs: an SDL2 one for Windows XP, and a Cubeb one for everything else.

I’d say this is where this particular story ends, but it isn’t:

The third option

I never quite got over the fact that I had to choose between bloat and non-portability: using SDL2 produced a DLL that was over a megabyte large, which is absolutely absurd when all I needed was something to ferry audio samples to the OS.

I thought that maybe I should ditch SDL2 and Cubeb, and just create a new backend that uses DirectSound – the very audio API that Cave Story itself uses. That would be very minimal (incurring next to no DLL bloat as DirectSound is a system library) and it would be guaranteed to support any platform that Cave Story runs on.

However, I could never figure out how to use DirectSound: it wasn’t as easy as a callback function asking for samples every now and again – instead it looked like you had to do some crazy low-level stuff involving filling an audio buffer with data as it was being played. In hindsight, it was just your usual push-API double-buffer stuff, but back then it was just gobbledygook to me.

So I began to look around for a DirectSound wrapper library – something small that would provide a nice simple API for steaming audio. It was while looking for this that I found what would become one of my favourite libraries, even today:

I’d found a curious little library called ‘mini_al’, and it claimed to be exactly what I was looking for: a small library that provided an API meant for streaming audio using DirectSound. Except it wasn’t just DirectSound: it supported WASAPI, WinMM, OpenSL, ALSA, PulseAudio, JACK, CoreAudio, and so on; it supported everything.

But this is bloat, right? All I needed was DirectSound. Well that’s the amazing thing: this library is the exact opposite of bloat. Don’t want WASAPI or WinMM code wasting space in your executable? You can just get rid of it!

What I’d found was a single-header-file library – a library that prioritises portability, ease of integration, and minimising bloat. Unlike typical libraries, these ones aren’t compiled on their own and installed to your system as an unmodifiable binary; rather, these ones are compiled straight into your program from source. Because of this, these libraries often allow users to disable code they don’t need with nothing more than a #define.

With this, I didn’t have to sacrifice portability or efficiency: I could have both:

BackendSize of binarySupports Windows XP
SDL21.22MBYes
Cubeb553KBNo
mini_al389KBYes

And so clownaudio gained a third backend. I could have discarded the other two, but I liked the idea of maintaining a small collection of backends, even if one of them completed trumped the others.

To this day, mini_al (or ‘miniaudio’, as it’s now called) remains clownaudio’s preferred playback backend.

Closing

Honestly, I was hoping to cover more in this part, but somehow writing about this one subject has already taken a couple of hours. In the next part, I’ll cover the first step in clownaudio’s transition from a component in a Cave Story mod to a standalone audio library.

Advertisement

5 thoughts on “The tale of clownaudio – Part 3

  1. Hi
    i have serious problem playing your “hyper & super sonic in sonic 1” hack
    when i reboot on sega cd mode to get knuckles chaotix music ….. so the rom plays but no sonic sprite appear on the screen

    i using Kega Fusion 3.64 with all Sega CD / 32x / genesis bios running ok
    i am using geforce 210 …i am also tested on other computer and i got the same problem

    the set:
    CartBootEnabled=1
    was made ok

    look the video:

    the reboot was made at 30 seconds of the video
    can you fix that ? please
    sorry i can post on sonic retro forum

    thanks

    Artur

    Like

    1. It’s a bug in Kega Fusion: when the Sega CD mode is enabled, DMA transfers stop working. You can see this same issue in Sonic 2 if you enable Sega CD mode while playing it. I’d recommend using another emulator instead.

      Like

      1. question: gens emulator will works or not ?
        this have genesis roms and sega cd support
        but i don´t how make segacd mode reboot while genesis rom still works like as fusion does
        how?

        thanks

        Like

  2. oh i see your reply on other place sorry
    hi
    more questions
    how to do the segacd reboot on genesis plus gx ?

    genesis plus gx will run on xp ?
    some plan to add spin dash on this hack ? will be very cool i think

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: