UGen for dynamics processing: dyna
Chuck enthusiasts, * introduction Ever since encountering Zolzer's DAFX (great implementation-level guide on music-dsp... along with Roads Computer Music Tutorial), I'd been wanting to implement some of the basics for my own edification.
From time to time chucking, I don't leave enough volume headroom (too loud) on the dac, so sometimes, especially when playing a drum sample with sndbuf, the sound will clip at the dac on my soundcard and make an upleasant crunchy noise. This inspired me to write a Limiter.
* background Dynamics Processors are objects that monitor the signal level of a sound, and adjust a gain factor to accomplish some musical goal: - Compressor- reduces the dynamic range of events above a threshold so that they are more uniform in volume. By applying gain afterwards, this results in a louder signal overall. Used frequently in music production to produce steadier parts and louder masters. - Limiter- keeps the signal level under some threshold by applying inverse gain. - Noise gate- zeros the signal when it is under some threshold to get rid of bare audible noise. - Expander- increases the overall dynamic range by making events under a threshold quieter by a factor. Used in some cases with a Compressor to preserve the dynamic range of a signal being transmitted. for more information, see RaneNote on Dynamic Processors: http://www.rane.com/note155.html at * you are the prototype I began by drafting the processing code in ChucK. It was nice to be able to prototype in a higher-level language. Once things seem to work, I was able to figure how to turn it into a native chuck object (for performance and vanity's sake). You can use "dyna-limit-chuck.ck" to test the chuck version "limiter.ck". * implementation Since the processors differ only by the gain transfer function, I was able to implement them all with the limiter algorithm, by changing a few constants- the threshold, whether the processor acts above or below the threshold, and the slope/ratio. First, I copied the skeleton from ugen_xxx.{h,cpp} to use as a model. Then I began by creating a data object to hold the state of the processor. Next I was able to implement a tick function by translating the chuck code, and implement controls (chuck methods) for the parameters. Finally, I was able to start testing it and write samples! (Using the same basic design, one should be able to make a processor that does all of these things at once by making a compound transfer function with thresholds for each mode: http://www.rane.com/note1556.html I will leave that work until "dynb".) Though there is a peak-level CPU usage difference between the native version and the chuck version, it's not as big as I thought. * chuck samples So that you can play and get an idea of the sound of each of the effects, I've included sample code for each of the modes. Each sample plays a bit of music: first with dyna bypassed (op=-1), then with the processing on. (dyna-limit.ck, dyna-gate.ck, dyna-compress.ck, dyna-expand.ck) Warning: dyna-limit.ck can be loud and will clip at your dac, so turn down the main volume of your soundcard. * documentation I have included some suggested documentation in dyna.tex. * how to install Add "ugen_gkc.h" and "ugen_gkc.cpp" to your chuck sources, and to the build process. You'll also have to add the following to chuck_compile.cpp: towards the top of the file: #include "ugen_gkc.h" towards the middle of load_internal_modules(): //load gkc! EM_log( CK_LOG_SEVERE, "module GKC..." ); load_module( env, gkc_query, "gkc", "global" ); * conclusion I hope this is fun, and I hope this is useful. Let it never be said that "the chuck stops here." Graham
participants (1)
-
Graham Coleman