The Csound Blog by Jacob Joaquin email jacobjoaquin@gmail.com web www.thumbuki.com/csound/blog (C)2007 Jacob Joaquin Licensed under Creative Commons (see below) 2007.02.14 Home Brewed Convolution According to wikipedia, convolution is "a mathematical operator which takes two functions f and g and produces a third function that in a sense represents the amount of overlap between f and a reversed and translated version of g."[1] However, this explanation tells us little about convolution as applied to audio. In "The Transformation of Speech Into Music," Dr. Richard Boulanger writes "the convolution of any two sounds corresponds to their 'dynamic spectral intersection.'"(pg. 89)[2] In other words, convolution allows us to "infuse" the pitch and timbre qualities of two digital audio sources. The applications of convolution are far and great. You can convolve a dry guitar signal with an impulse response of a subway station, which makes the guitar sound as if it was originally recorded in that subway. If you convolve a synth with an impulse response of a genuine Moog low pass filter, the synth will now sound as if it was processed with a Moog. Any audio source can be used as an impulse response, whether it be a piano note, the laughter of a child, or even the snap-crackle-pop of your cereal. In essence, every sound is a filter with convolution. Recording an Impulse Response Let's say we wanted to "borrow" the reverb properties of a large cathedral. Set up a mic (or two for stereo) at the position of the listener. At the desired location of the sound source, set off a quick high energy burst of white noise. Record this burst and the decaying reverb that follows. Afterwards, crop the relevant portion of the recording, and what you have left is an impulse response file of that cathedral. Impulse Responses in Csound I use Csound to generate two impulses and store them in f-tables. The first impulse response is of the reverb opcode. The second impulse is a burst of white noise with an exponential decay. The Instrument Csound comes pre-equipped with the convolve opcode, which utilizes an FFT based convolution algorithm. In order to use it, you are required to use the cvanal utility to pre-anaylize the impulse responses you wish to use. I highly recommend you to check it out. However, I did not use this method. Instead, I built my own direct convolution instrument that use my generated impulse responses. Direct convolution is very mathematically intense. To quote Erik Spjut from the Csound book, "If signal b is 256 samples long, the convolution sum requires 256 multiplications and additions to produce one sample..."(pg. 508)[3] The Audio Example There are five short audio clips in this example. 1) A percussive synth note with a rising pitch. 2) An impulse response of the reverb opcode. 3) The synth note convolved with the reverb impulse response. 4) A burst of white noise with exponential decay. 5) The synth note convolved with the white noise. The Verdict Originally, I was hoping my instrument would be a viable way to bypass using the cvanal utility for short impulses. I learned that direct convolution is much too processor intensive, even with impulses as short as one second, to be a viable solution. The sample rate of this example is set to 4000, and still won't run in real-time. Even though my instrument is mostly useless, I decided to write about it in hopes that this information will be useful to somebody and to raise convolution awareness. Further Study There are three sources I highly recommend to anyone interested in convolution. The first is The Computer Music Tutorial by Curtis Roads.[4] The second is Erik Spjut's chapter "Convolution in Csound: Traditional and Novel Applications" in The Csound Book.[3] The third is Dr. Boulanger's "The Transformation of Speech Into Music."[2] I would also like to mention that you don't need Csound to explore convolution. For Mac users, I highly recommend Tom Erbe's Soundhack.[5] On the PC, you can use Sound Forge.[6] As for Linux, let me know. References [1] Convolution @ Wikipedia http://en.wikipedia.org/wiki/Convolution [2] Boulanger, Richard C. The Transformation of Speech Into Music San Deigo: University of California, 1985 [3] Boulanger, Richard C. (Editor) and Spjut, Erik The Csound Book Ch. 26 Cambridge, Massachussetts: The MIT Press, 2000 [4] Roads, Curtis The Computer Music Tutorial Second Printing Cambridge, Massachussetts: The MIT Press, 1996 [5] Soundhack http://www.soundhack.com/freeware.php [6] Sound Forge http://www.sonymediasoftware.com/Products/ShowProduct.asp?PID=961 Permalink http://www.thumbuki.com/20070214/home-brewed-convolution.html License (cc) Creative Commons Attribution-ShareAlike 2.5 You are free: * to Share -- to copy, distribute, display, and perform the work * to Remix -- to make derivative works Under the following conditions: * Attribution. You must attribute the work in the manner specified by the author or licensor. * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. * For any reuse or distribution, you must make clear to others the license terms of this work. * Any of these conditions can be waived if you get permission from the copyright holder. http://creativecommons.org/licenses/by-sa/2.5/ sr = 4000 kr = 4000 ksmps = 1 nchnls = 1 ; instr 50 Sound ; instr 60 Generate Reverb Impulse ; instr 61 Generate White Noise Impulse ; instr 70 ( Sound ) * ( Impulse ) ; Master Volume #define VOLUME #5000# ; f-tables gibuffer ftgen 100, 0, 4096, 10, 0 giverb ftgen 103, 0, 4096, 10, 0 ginoise ftgen 104, 0, 4096, 10, 0 ; ---- Sound ---- instr 50 idur = p3; kenv linseg 1, 0.1, 0.4, 0.3, 0, idur - 0.4, 0 kenv2 expseg 1, 0.5, 2, idur - 0.5, 2 aosc oscil kenv, 262 * kenv2, 3, -1 out aosc * $VOLUME endin ; ---- Generate Reverb Impulse ---- instr 60 idur = p3 isize = sr aptr init 0 aclick linseg 1, 1 / sr, 1, 0, 0, idur - ( 1 / sr ), 0 areverb reverb aclick, 1 tabw areverb, aptr, giverb aread tab aptr, giverb aptr = aptr + 1 aptr = aptr % isize out aread * $VOLUME endin ; ---- Generate White Noise Impulse ---- instr 61 idur = p3 isize = sr aptr init 0 kenv expon 2, idur, 1 kenv = kenv - 1 anoise noise 1, 0 anoise = anoise * kenv tabw anoise, aptr, ginoise aread tab aptr, ginoise aptr = aptr + 1 aptr = aptr % isize out aread * $VOLUME endin ; ---- ( Sound ) * ( Impulse ) ---- instr 70 idur = p3 iimpulse = p4 isize = sr kpass = 0 amix = 0 kbuffer init 0 ; Generate Tone kenv linseg 1, 0.1, 0.4, 0.3, 0, idur - 0.4, 0 kenv2 expseg 1, 0.5, 2, idur - 0.5, 2 aosc oscil kenv, 262 * kenv2, 3, -1 tabw aosc, kbuffer, gibuffer ; Convolution Loop thestart: if ( kpass >= isize ) kgoto next kptr = kbuffer - kpass; kptr = ( kptr >= 0 ? kptr : kptr + isize ) averb tab kpass, iimpulse anote tab kptr, gibuffer amix = amix + ( averb * anote ) kpass = kpass + 1 kgoto thestart next: ; Finish Up the Instrument kbuffer = kbuffer + 1 kbuffer = kbuffer % isize out amix * $VOLUME * 0.2 endin f3 0 8192 -7 -1 4096 1 4096 -1 i50 0 1 i60 2 1 i70 4 1.4 103 i61 6 1 i70 8 1.4 104 e