Previous Post

Project: SDL_sound 2.0

Next Post
Project: SDL_sound 2.0
1 / 4
DESCRIPTION

In my generation, it's a novelty (and a horror) to find a piece of code you wrote as a child.

If you're in your teens now, don't worry, GitHub will save everything you ever tried to write. You will still experience this feeling in your 40's, but you'll know exactly where to go to find it.

When I was 17, I wrote a LOGO interpreter in C--having never written any serious C code before--as a requirement to graduate high school. I figured this was a mature thing to do, and C was more "powerful" than BASIC, which was pretty stupid in retrospect because LOGO is 1% about drawing lines on the screen and 99% about parsing strings, which is not something C is powerful for at all.

Five bazillion buffer overflows and one near-fatal failure to convert from degrees to radians later, I presented the interpreter as my senior exit project, and of course it crashed the MS-DOS machine halfway through the demonstration, but not before producing something like this...

...which impressed everyone just enough that bringing a 486 and CRT monitor to school on the bus were worth it.

But I look back sometimes, knowing things now that I didn't know then. Like programming language interpreters don't parse every line of the program as they are about to execute it, including parsing them again as the program loops back over that line. Concepts like Abstract Syntax Trees and lexers and parsers and Semantic Analysis weren't even on my radar, let alone in my project.

Looking back, it was clear what my goal was with the project: I wanted to get the thing to run at all, to show what I was thinking about what education might do with access to technology. We might all be lugging gigantic desktop machines onto a school bus some day, you know! Since that was my goal, doing a deep dive into compiler design (and trust me, that dive is deep) would have made me fail to build anything, even if I had more than a few months for my senior exit project. One did not simply Google "compiler design" in 1995. What was I going to do? Read the Dragon Book? It's been 23 years, and I'm still trying to read it! All I had was brute force, and the blind optimism that comes from not knowing when you're in over your head, but that's what got the job done.

That was the Toby programming language, attempt number 1, which you can see the source code to here because I'm a pack rat. You can also see where I made different mistakes in rewrites number two, three and four. It's currently on the fifth rewrite. I'll probably die of old age on the sixth, stubborn fool that I am.

I told you this story so you will be prepared for the moment when you also find your old source code somewhere: on a USB drive in the back of a drawer or on an abandoned laptop you'll pull out of your parents' attic in 20 years to see if it still boots.

When this happens, I want you to push past the initial feelings of shame, because you have to let yourself off the hook for all the things you didn't know at the time, but also because there's something really valuable there beyond remembering how you discovered that delete and delete[] aren't interchangeable. You should stare at those lines of code for a long time, quietly, and think about what your goals were when you wrote it. And you should think about how your goals have changed since. Rewrite after rewrite, my goals changed as I learned more about technology and more about the world.

This month, I spent time updating SDL_sound, much like I did for PhysicsFS last September. SDL_sound has been collecting dust a long time; the copyright on it hadn't been updated since 2001. So I stared at those lines of code for a long time, quietly, and thought about what my goals were when I wrote it.

SDL_sound was built to be the audio version of SDL_image. It was meant to gather up libraries for loading all the various file formats that exist in the world and hide them behind a single, SDL-friendly API. SDL_sound would take an audio file through a RWops (SDL's generic i/o interface) and spit out PCM data that you could feed to SDL's audio callback to make noise. You didn't have to figure out how to talk to a dozen different libraries with different interfaces. You just handed it a thing and then took what it handed back, whether SDL_sound was talking to libvorbis behind the scenes, or ModPlug or Timidity, etc.

What were my goals, though? Obviously ease-of-use, because the first letter of SDL stands for "simple." But other choices reflect goals of the person I was in 2001.

In 2001, I was just done working for a Linux game company. Almost all of my development was done on Linux, and I wanted to build tools that made it easier for Linux developers to build Linux games. I was building a library for a programmer that would say "ah, I would like to use this," and then would chant an incantation with the tongue of the ancient ones, like "apt-get install libsdl-sound1.2-dev" and then the system would automagically figure out how to get all those libraries installed, so that SDL_sound could talk to them on behalf of the programmer. Being a library--a Linux library!--it made sense to use the LGPL for its license, instead of the only other license in existence.

But the goals I had over time changed, based on problems I encountered as a game developer in the years since.

First: there are original Linux games out there--TuxRacer and such--but overwhelmingly, in the last decade and a half, this is not where game development happened. No judgment here, I promise, but even the individuals and indies working in their garages built Windows games on their Windows machines. Since Windows (still!) doesn't have a package manager and adding external libraries to Visual Studio is sort of a pain, my original goal was counter-productive. Not only did you have to get SDL and SDL_sound added to your project, but maybe 5 or 6 other libraries on top of it, each with their own quirks and build systems. And then you had to do it again for the Mac.

Additionally, the LGPL license itself turned out to be counter-productive. In 2001, I was totally ready to scream "FUD!!" at people that suggested the LGPL was "viral" but after a while, I got tired of this. I can't change people's fears. Even within the community of true believers, no one understood what the actual rules of the GNU licenses were. Do you? And then the iPhone came along, and it was a legit problem: you couldn't comply with the LGPL on a platform that requires signed binaries and doesn't allow side-loading, so we were about to be locked out of what might turn out to be the most important computing platform on the planet.

So I started changing licenses from LGPL to zlib. The immediate benefit is that it wasn't a massive wall of text. Here is the entire license on a single powerpoint slide from my Steam Dev Days presentation on SDL2:

For comparison, at that font, the LGPL would take 22 slides.

The zlib license basically says:

Don't take my name off this source code.

Don't sue me if it breaks.

Otherwise, do whatever you want.

It doesn't force you to share your code or your changes to my work, it doesn't care if you statically link it, it doesn't demand you copy-and-paste the license into your documentation. You don't need a written offer to mail people anything. Basically it gives the author the most basic protections and then gets out of everyone's way, which fits my general disposition way better. What I wanted to do was share, but as I told my preschooler all the time, you can't make someone else want to share back.

The license change opened up new platforms to SDL: iOS, game consoles, embedded devices. We found out they used SDL2 on all those NES and SNES Classic units, so the license change got SDL onto 7.5 million new devices. The license change also got us access to 14.8 million Nintendo Switches. Not to mention the 1.2 billion iPhones.

Accordingly, the license needed to change on SDL_sound, too, and now it has. I hope it will let people drop it into their games with confidence.

The other major change was ripping out the external libraries. Now everything included with SDL_sound is built as part of SDL_sound instead of making you track down external libraries. Some of SDL_sound's decoders were hand-written for the project, like the ones for .wav files or Shorten audio, but others needed libvorbis, libspeex, libflac, ModPlug, MikMod, Timidity, etc, etc. Not only did you have to track down all these libraries yourself and hope they were compatible versions, but you had to comply with each library's license separately. The intention of SDL_sound was to be helpful, but this was a hassle.

Fortunately, there's been a little political movement celebrating "single-header libraries" in recent years, thanks to a ton of impressive work from people like Sean Barrett. The idea is you get something that functions as a library, but it ships as a single C header, and is usually public domain code. You literally just include it (#include it!) in your project and go.

A good example of this is zlib (the library, not the license), which is a big project, with code to keep it friendly to ancient and foreign platforms and compilers. It is 13452 lines of code across 26 files. But Rich Geldreich released a single-file implementation called miniz which can do the same thing in 700 lines of C that you can drop right into your project as a single header, since you don't care about 16-bit MS-DOS support anyhow.

Other libraries exist like this. Sean Barrett has an Ogg Vorbis decoder in a single C file and David Reid did similar things for MP3 and FLAC support.

And, it turns out, libModPlug is now in the public domain! This let me fix several things I hated about it: it being C++, it not being able to have different decoding settings for different files, etc. Since I was now able to just include it with SDL_sound, I could make any dramatic changes I need--including breaking the API--without getting a Pull Request approved and waiting for a new version release. Now it just builds with the rest of SDL_sound. As an added bonus: libModPlug now supports MIDI decoding too, so we could dump Timidity as well.

Other changes to SDL_sound: we're on CMake now, and the only external things it references are from SDL (no C runtime). Since SDL itself doesn't use the C runtime either, it means you can link it to anything on Windows without worrying about what C runtime your project needs, or if it needs different runtimes for different build types. It's a small detail that was tedious to achieve, but falls in line with making things easier for game developers.

The next steps on this project are to let people catch up and test it, and decide to bless this as a formal 2.0 release. Maybe we'll add some more audio formats. Eventually we might decide to add new features, maybe to replace SDL_mixer as a go-to project for simple mixing needs. But for an initial 2.0 release, I'll be happy that it now matches my more recent goals.

SDL_sound's project page is here and revision control is here.

(photo credit: that awesome RMS/Drake photoshop, in honor of the stripping of the LGPL, came from a Google Image Search for "disappointed Richard Stallman" that landed me here.)

Ryan C. Gordon PATREON 3 favs
VIEWS1
FILES4 files
POSTEDJul 21, 2018
ARCHIVEDJul 21, 2018