The Audio Diaries Ch. 1 — May I Have Your Attenuation Please?
In an effort to resurrect my blog, I’ve decided to journal my foray into digital audio processing. I’ve been dabbling in electronic music for many, many, years now, but I don’t feel like I ever had a true understanding of the fundamentals of digital audio. There are a lot of mathematical concepts that are core to how sound works (duh) that I’ve mostly glossed over for the sake of time. Instead, and like most people, I learned about the effects of these fundamentals (low-pass filter cuts out high frequencies, high-pass filter cuts out low frequencies). Given how much I’m interested in the art, I think it’s important that I spend time understanding exactly how this stuff works. There’s a lot to learn, so hopefully there will also be a lot to post.
So here we go. Down the rabbit hole.
Resources
Robin Schmidt’s Music Engineering Tools — The first important resource I came across happened years ago when I made attempt number one to learn about how digital audio worked. It was then that I came across probably the most important beginner’s resource to digital audio anybody could possibly find. I found this resource again a few days ago while researching the same basic principles and was instantly reminded why this site is so important: the articles provided here are well written with just enough math to understand the concepts but without going into crazy abstract mathematical details. In short, this is probably the closest to a set of “explain to me like I’m 5” articles without the impractical analogies… and maybe a little bit more math. I don’t think you will find any simpler explanations of these concepts anywhere else on the internet, though.
The ruby-audio gem — It’s a little dated and extremely limiting, but the ruby-audio
gem let’s you quickly create .wav files with a bunch of data fairly quickly. I’ve been using this to experiment with simple sine waves (I’ll show this in the next post) to get a practical understanding of the concepts I’m reading about.
The First Goal: A VSTi Plugin
One of the things I want to do is make it really easy to prototype sounds and filters I’m implementing, and Ruby is the obvious choice when it comes to quick prototyping. The ruby-audio gem works alright, but being forced to write a wav file to disk and load it up into an audio editor makes my workflow slow. Being able to stream audio signals directly to a DAW (Digital Audio Workstation, i.e., Ableton Live, Reason, Pro Tools, Cubase, etc.) would make things much simpler, but this means I need to write a VST plugin in order to get that audio into those programs.
The problem is, VST’s are pretty much only developed via a C++ SDK that Steinberg has tight control over, and there is very little documentation on how to roll your own VST plugin without the SDK (there are open source implementations, but I won’t waste my time reverse engineering this stuff). Furthermore, the Ruby landscape is pretty much void of anything that even comes close to any audio libraries (ruby-audio is one of the very few exceptions), so I’m working in the dark here.
Fortunately I have experience embedding a Ruby interpreter into C applications, so my next step will be to take a really simple VST plugin base and bind all of the hooks down to a Ruby script running in the background that I can change at runtime, or at least load up without recompiling. I already compiled the AGain VST sample that comes with the SDK and have a good idea how to hook this up to a Ruby interpreter, but there are two things I haven’t yet figured out:
- A VST host (DAW) has to load a VST plugin as a DLL (I say DLL to disambiguate “library”, which might be confused with a RubyGem or some plaintext .rb file; these DLLs are compiled down to machine code with exported symbols to be loaded by a process) file on disk, and a plugin does not control the process, so I can’t just “create a plugin” by launching a Ruby process and requiring some library code. I have to create a single C++ VST plugin (by compiling a DLL) that calls out to Ruby from the hooks provided by the SDK’s API. The problem is that I don’t really know how I’m going to load arbitrary Ruby code if I can’t control the process, and more importantly, how I’m going to change the code on the fly, since I won’t have an interactive console. I’ll probably have to point to a file on disk that gets reloaded on modification, unless I can spawn up a mini web-server from the plugin that evaluates code passed in via some fake irb console. DRb won’t work, since I can’t pass Procs across the wire, and that will definitely be necessary.
- The AGain sample is a “VST” plugin. This is different from “VSTi” in a way that I am not fully aware of. Ultimately I want a VST plugin that produces new audio samples, not filters existing audio samples, and that is what a VSTi (or VST instrument) plugin is for. The problem here is that I’m not sure if I need to use a different API to create a VSTi. I’ll have to keep digging for a sample on this. It might be pretty easy to make, but I just don’t yet know how.
Once the VSTi plugin is finished, I should be able to load up Ableton Live and play my data directly into a buffer, record it, and analyze the differences… as well as hear it live. It will also give me a chance to create a VST library that seems to be missing in the Ruby ecosystem.
That’s it for now.