Welcome

Welcome to Teragon Audio, provider of audio plugins, utilities, and guides for those looking to develop their own audio software. This is the development blog, if you are looking for the official website please visit http://www.teragonaudio.com.
Showing posts with label extranotes. Show all posts
Showing posts with label extranotes. Show all posts

Release day!

As promised, I finally got around to polishing up and releasing all the plugins I've been working on during the holidays. Specifically, ChaosChimp, NotNotchFilter, and ExtraNotes all got updates pushed. I'm holding back on HiLoFilter because I'm still not happy about the clicking noise which happens around the dead zone.

Anyways, here are some screenshots from the final versions of all plugins. Click on the thumbnails to see a full-sized screenshot:

BeatCounter 2.1

ChaosChimp 1.0.0

ExtraNotes 3.0.0 (text editor view)

ExtraNotes 3.0.0 (image editor view)

NotNotchFilter 2.0.0

Death to boilerplate

I made some good progress on ExtraNotes yesterday, it can now save the note correctly and serialize the image data to a base64-encoded string. It's pretty much ready to be released, but when I was testing it I realized what a pain in the ass it's going to be to make it compatible with all hosts. Text input in VSTs is always somewhat tricky, since many hosts like to intercept the keystrokes for themselves. Anyways, I'm just going to test under the ones that I already have, and wait for the bug reports to trickle in. :)

In doing the XML serialization work, I had the idea to make a common base class for the Teragon plugins, since they all have a bunch of identical boilerplate code in them. This wasn't such a bother for the parameter handling, since all of those functions were simple one-liners, but the serialization routine was starting to get rather complex and it pained me to keep copy-pasting it between plugins. So, I introduced a new abstract base class which extends AudioProcessor and takes care of all the PluginParameters related stuff. Doing this eliminates a ton of boilerplate code from all the plugins, making them much simpler to maintain and understand.

Also, today I fixed a nasty bug in NotNotchFilter where a small (but audible) click could be heard when moving from bypass to filter states. The reason for this is that the first "tick" of the knob ended up being a few hundred Hertz, which is quite an extreme difference to apply suddenly to a filter. Exponential scaling didn't work very well in practice for NotNotchFilter, because the frequency range goes from 0-20kHz, so the first half of the knob's motion would only cover ~10Hz, and the second half would race through all remaining frequencies.

So today, I busted open the venerable yet forgotten "Grapher" program which ships with Mac OSX. I discovered (or perhaps forgot) that one of the lesser-known features of this program is that you can generate a point set, and then interpolate through them. So I crafted a curve which would work well with the knob's range, and generated a 5th-degree polynomial equation to fit the points. The result is that now the knob is very comfortable to use, and the click is gone! I'll probably need to generate another set of curves for HiLoFilter, which has a similar problem but a different knob action.
Yay for math!

The return of Arooo

Did a bit of work on ExtraNotes today; last night I had a revelation about how to solve the problem of the GUI not updating properly when audio playback is paused. The solution is actually quite simple -- ConcurrentParameterSet should have pause/resume methods which are called when the playback is paused/resumed, and when paused, all realtime parameter changes are executed right away. Since playback is paused, the risk of priority inversion (which, for the record, is the reason that ConcurrentParameterSet is so damn complex) does not exist and the parameter updates can be safely executed.

The solution worked like a charm, and I am thinking about doing a bit of minor re-architecting in PluginParameters so that other plugins can use this solution per-default. As it stands, the other plugins which use ConcurrentParameterSet don't really need to execute parameter changes when playback is paused, so it's not such a big deal.

Yeah, at this point I'm now sitting on 4 plugins which are essentially finished, but haven't been released. The reason I haven't done any proper releases of these plugins is mostly laziness -- doing releases means getting out a bunch of different laptops, making builds, doing sanity checks, making the zipfiles etc. It's not hard work, but it's labor-intensive and takes time. Since I've got such a great creative burst going these days, I'm reluctant to blow it on the mindless repetitiveness on releasing software. But I promise that will change soon, and shortly after New Year's, I will make a huge release day and push everything out "into the wild".

On the subject of creative streaks, I started looking at Arooo again, and am now hacking it into plugin form. Arooo is a standalone app I did at last year's MusicHackDay Stockholm, and it was primarily intended for trying to stop a bad habit that our puppy was developing -- howling when I left the house. The software would open the default audio device, look for sounds which roughly matched the frequency signature of the howls, and then play a nasty noise if detected. The hack was easily done in the required 24 hours for the hackathon, and it was fun to demo.

Surprisingly, when I put Arooo into action, it did very well. I set the program up to log events to the screen, and then recorded the audio when I was gone and cross-referenced them against each other. It showed real promise, detecting the input noises at very high reliability. I haven't done much with the software since then, but I have been meaning to generalize it and make it into plugin form. When finished, the plugin will:

  • Allow the user to load in an audio file for profiling
  • Process audio in realtime, searching for signals which match the profile
  • Set a "tolerance" for how close the input signal must match the profile
  • Trigger an event when the input signal matches, which can include:
    • Playing another sample (could be used to build a drum-replacement sampler)
    • Playing a MIDI note
    • Sending a MIDI CC message
    • Executing a shell script
After one day of hacking, I made a basic GUI and re-architected some of the initial hackathon code to be a bit more generic. I still need to generalize the profiling algorithm, which was the key part of making Arooo work.

Nearing release day

My girlfriend is in town for New Year's, so I haven't been hacking much (gotta appreciate the better things in life, you know). We were also supposed to spend Christmas together, but due to some screwed-up travel plans things didn't work out... and hence, my huge hacking spree during the holidays. Anyways, I have done a bit of work on the plugins during her time here, since she also needs to study for exams.

I have managed to get all of the plugins building on Windows and Linux, and now have 32/64-bit builds on all three platforms. As usual, Windows proved to be the problem child of the lot, and I needed to make two more patches to tinythreadpp to get it building on 64-bit Windows. Actually building on Windows isn't nearly as painful as doing anything git-related on Windows, due to the horrendous command-line situation on that platform.

As expected, porting to Linux was trivial given that they built on Mac OSX; it was just a matter of pointing GCC to the correct source paths and sorting out the compile flags for C++11 support. At any rate, I just need to zip up and organize the binaries and then put out the word. Quite a nice way to start out 2014, I think.

Using the Renoise demo, I was able to test out the Linux plugins (MrsWatson has experimental GUI support, but it's not realtime, so it's not suitable for doing actual GUI testing). Although Renoise is in general a rather difficult host to learn, dropping the plugins on the master channel is not terribly difficult, and I was pleased to see how well things worked out of the box. Text editing, graphics importing, etc., all worked. Normally this GUI-type stuff is always a complete pain with Linux, but apparently not with Juce!

However, there is one problem, which is that the GUI for ExtraNotes should behave a bit differently than a realtime-audio plugin, and for this reason the GUI "seems" a bit unresponsive, even though it's simply because the realtime event loop isn't being processed. I need to solve this problem, which I don't think will be terribly difficult.

PluginParameters improvements, and introducing ExtraNotes

This morning I intended to "briefly explore" a concurrency bug in PluginParameters which had been bothering me ever since I started porting TeragonGuiComponents over to Windows. Although the demo ran great, and the framework required very little work to port to Windows, I was annoyed that the demo app was crashing on shutdown. This might normally be forgivable for a desktop app, but for a plugin this means that removing it from a channel will crash the host, so it's kind of a big deal.

Anyways, my "brief exploration" resulted in a full day of hacking PluginParameters, but at least now I've bumped the version to 3.0 and fixed a ton of bugs in the process. Also I renamed several classes in the library, since some classes were starting to get quite verbose (namely, ThreadsafePluginParameterSet is now ConcurrentParameterSet, which is still quite long but overall better). Unfortunately some concurrency bugs are still lurking in the framework, mostly having to do with calling set() or delete on a ConcurrentParameterSet directly after creating it. I would really like PluginParameters to be able to guarantee to the user that it is ready to do anything after the constructor returns, but unfortunately this is in practice very difficult to accomplish.

The good news is that in practice, a plugin should never need to call set() or delete on a parameter set immediately after creating it. However, I dislike shipping code with known bugs, no matter how small.

Anyways, I also made some progress yesterday on ExtraNotes, which is the renamed version of AUNotes. This will actually be the second time I've renamed the plugin; the name before AUNotes was "Notepad", which I think is far too generic and has poor search visibility. This name change reflects something bigger and more exciting -- the dropping of the "AU" from the plugin.

ExtraNotes will actually have an AudioUnit version, but unlike its predecessors, it will be available for other plugin containers (namely VST) and operating systems. A Windows/Linux port of this plugin has been on my wishlist for many years now, and I'm glad that I could finally do this using Juce and TeragonGuiComponents. Here's some preview screenshots:

Editing a note
Images are finally supported!
Yes, that's right! ExtraNotes will support importing images and store them in the note for you! This has been a looooong requested user feature, and using the Juce image framework, it actually wasn't terribly difficult to accomplish. The plugin will support two "tabs", so you can have both text and a single image. You can also import a text file from disk into the text tab, in the exact same way that you can load an image to the image tab.

Currently the plugin does not serialize the image during state save/restore, and although the text notes should, it's completely untested. I'm not sure how well Juce's XML serializer will deal with raw binary data like this, and I might need to serialize the image myself into a series of integers (yuck, let's hope it doesn't come to that).

So yeah, today I had originally planned to do Windows porting, and to be fair I did do some. The PluginParameters test suite now builds and runs on Windows, which is a big improvement, and the TeragonGuiComponents demo also is running on Windows without crashing (yay). However I probably won't have time to build Windows versions of the other plugins I did over Christmas, which means that I will probably end up doing a huge batch of releases sometime shortly after New Years.