In this post I’m going to discuss two new features I have added to the Match Envelope plug-in that I’m pretty excited about. And with some additional bug fixing, it’s in a good workable state, so I can offer up the plug-in as a Beta version.
The first of the new features I added is an option to invert the envelope, so instead of matching the source audio that you extract the envelope from, the resulting audio is opposite in shape. Of course this can further be tweaked by use of the “match strength” and “gain” parameters. The actual process of doing this is very simple; take the interpolated value (from cubic interpolation) ‘ival’ and subtract it from 1 (digital waveforms in floating point representation all have sample values between -1 to 1). As simple as this was, it did introduce a bug that took a long time to find.
Occasionally I would get artefacting after applying the process when inverting the envelope, and I discovered that the resuling interpolated value was nan in these cases (nan = not a number). When the source audio consisted of sharp attacks, and thus sharp rises in the waveform, the interpolated value exceeded 1 by a small amount. Then, when it gets to this point in the formula for calculating match strength:
it will result in an imaginary number when matchStr is around 0.5. In essence, this part of the formula ends up trying to square-root a negative number. The easy fix for this was just to take the absolute value of ‘ival’ such that pow(fabs(ival), matchStr)) will then never result in nan. This is a better solution than to just “floor” ival to 0 if it is negative because this will actually alter the audio slightly by messing with the interpolation.
The second feature I added is a “window offset” parameter, which shifts the envelope left or right. Oddly enough, this one took less time to implement and required less testing/fixing than the invert feature even though it sounds more complex to code. In fact, it’s pretty simple as well. Similar to a circular buffer, instead of shifting the elements around in the buffers that contain the envelope data, I just offset the cursor that points to the location in the buffer.
If I want to shift the envelope to the left (the result will in effect anticipate the source audio’s envelope), the cursor needs to be offset by a positive number. If I want to shift the envelope to the right (emulating a delay of the envelope), the cursor needs to be offset by a negative number. This may seem a bit unintuitive at first, but we need to consider how the offset/placement of the cursor affects how the processing begins. i.e. if it is negatively offset, it will be delayed in processing the envelope data, thus shifting the envelope to the right.
Before moving on, here is a new video showcasing these new features, this time with some slightly more exciting audio for demonstration.
Lastly, in terms of bug fixing, I had to deal with an issue that arose in Soundforge due to the fact that it does not save the state of a plug-in once it’s invoked. In other words, when a plug-in is opened in Audacity, it is not “destroyed” until the program is exited; it only switches to a suspend state while it’s not active. This means that a plug-in’s constructor will only be called once, thus saving the state of parameters/variables between uses as long as the host isn’t closed. Soundforge does not do this, however, and this caused problems with parameter and variable reinitialization.
Fortunately a fix was found, but it has further reaffirmed that VST is not really built for offline processing, and while we can certainly coax them into it, I’ve hit several limitations in terms of what I can accomplish within the bounds of the VST SDK as well as inadequate support for the offline capabilities it does provide by hosts.
As such, this might be one of the last entries in this particular making-of series on the Match Envelope plug-in. I have learned a ton through this process, and through sticking it out when it became clear that this particular process is probably better suited to a standalone app or command-line program where I could have had much more control over things.
I look very much forward to developing my next plug-in, however, which will most assuredly be a real-time process of some kind, and I am excited to learn and to tackle the challenges that await! Without further ado, here are links to the beta of the Match Envelope VST plug-in: