Convolution in Csound
This is a short tutorial on how to do convolution in Csound, written by Rose Hammer.
Convolution
Convolution is a very useful dsp tool. It can be used to simulate the acoustics of a real space, or as a filtering tool. This tutorial will discuss the basics of convolution and their implementation in Csound, a powerful free audio development environment.
The basic idea of convolution can be expressed by a mathematical formula
\ \ \ M-1
y(n)= ∑ h(k)x(n-k)
\ \ \ k=0
where:
y(n) is the output signal
M is the length of the output signal (sum of the lengths of the two input signals)
h is one input signal
x is another input signal
(sorry about the stupid backslashes -- I couldn't figure out how to get the spacing to work properly)
This is an iterating process -- think of an impulse response taken from a room, and a musical passage as played in a dry room as the input signals. Each sample from the musical passage must be multiplied by all of the samples in the impulse response, and stored as a new sound file -- then the process moves ahead one sample, repeats, and is added in to the new signal but offset by one sample. In this way, each sample from the musical passage will be treated as if it had been played in the room.
here is an example of code that could realize this process:
//loop to increment through the samples in the first file
for (i=0; i<numsamps1; i++)
{
//loop to increment through the samples in the second file
for(j=0; j<numsamps2; j++)
{
//temp[j] stores the results of each round of computations
temp[j]=amp1[i]*amp2[j];
}
//add each round in to the total
totalsamps=numsamps1+numsamps2-1;
for(x=0; x<totalsamps; x++)
{
conv[x]+=temp[x];
}
}
or, here is a more efficient method:
for (i=0; i<n; i++)
{
for(j=0; i<m; j++)
{
//the output at 'n' is equal to the sum of the
//multiplication of the value at file1[n] and
//the value(s) at file2[0] through file2[m-1]
y[i+j]=y[i+j]+x[i]*h[j];
}
}
At any rate, you don't really have to understand the formula to be able to use convolution in csound, so don't be discouraged if this doesn't make sense right away.
Convolution in Csound
To do convolution in Csound, you will need to use the command-line utility cvanal. In OS X, you can run this from the Terminal window, if you have the command-line version of Csound installed.
Csound requires two different types of files for convolution: one .aif file, and one.con file, which is created using the cvanal utility.
To use the utility, type (in Terminal)
csound -U cvanal inputfile.aif outputfile.con
you will need to either be in the directory of the .aif file you are analyzing, or you will need to tell csound where to find the file. Also, if you do not specify a location for the output file, it will be created in your current directory.
If you are not comfortable using the Terminal, check out http://www.osxfaq.com/Tutorials/LearningCenter/UnixTutorials/LoseTheMouse/index.ws as a good reference for getting your feet wet.
So, for instance, say I have a file titled impulseresponse.aif, and I want to run the cvanal utility, I would move to the directory it is in, then type
csound -U cvanal impulseresponse.aif impulseresponse.con
you can ask for the output file to be named whatever you would like; it is a useful convention to name your .con files for their source .aif file, makes it easier to remember where they've come from.
Now we're ready to do some useful convolution in csound.
You should know that it is possible to do hard-coded convolution in csound, where you manually code the values for one of the files you want to use -- this is horribly inefficient, and I'm not going to go over it. Instead, we're going to skip to the useful way, which is the one that uses these .con files instead.
here is an example of a csound instrument, with .orc and .sco files:
.orc file
instr 2602 ; FFT CONVOLUTION
a1 soundin "fox.aif" ; SIGNAL A
a2 convolve a1,"highpass1k.con" ; SIGNAL B, (USE CVANAL TO MAKE)
out a2*p4 ; P4 IS SCALING FACTOR
endin
.sco file
i 2602 0 3 1
Csound uses the Fast Fourier Transform, or FFT, to make its calculations more efficient. Basically, the Fourier Transform is a reduction of a given segment of sound into its component sine frequencies, with measurements taken of their relative strength and phase. This is a bit of a complicated business, but it is very useful because it means that we can do convolution without having to go sample by sample.
If you want to know more about FFTs, check out http://astronomy.swin.edu.au/~pbourke/analysis/dft/ .
Anyhow, back to Csound. From the .orc file above we can see that csound wants the following:
"instr" instrumentname
a-rate variable 1 "soundin" file1.aif
a-rate variable 2 "convolve" file2.con
out a-rate variable 2 * a scaling factor (you'll be wanting to scale it _down_)
then we need to call the instrument we've created, in our .sco file.
i instrumentname starttime endtime scalingfactor
Now, you don't have to create a variable to scale your output by; it's simply a way to make the instrument more flexible. For instance, this way you could call the instrument several times, and change the scaling factor for each independantly.
This is how to do convolution in Csound.
Experiment with convolving different files together -- you can get some interesting results by convolving two distinctly different sounds.
One thing to note is that for each convolution you do, there will be silence for (I think) the duration of your .con file at the beginning of your output file. You will want to make sure that the duration of your output is at least as long as the combined length of both of your input files, or your output will get cut off.
Have fun !
Convolution is a very useful dsp tool. It can be used to simulate the acoustics of a real space, or as a filtering tool. This tutorial will discuss the basics of convolution and their implementation in Csound, a powerful free audio development environment.
The basic idea of convolution can be expressed by a mathematical formula
\ \ \ M-1
y(n)= ∑ h(k)x(n-k)
\ \ \ k=0
where:
y(n) is the output signal
M is the length of the output signal (sum of the lengths of the two input signals)
h is one input signal
x is another input signal
(sorry about the stupid backslashes -- I couldn't figure out how to get the spacing to work properly)
This is an iterating process -- think of an impulse response taken from a room, and a musical passage as played in a dry room as the input signals. Each sample from the musical passage must be multiplied by all of the samples in the impulse response, and stored as a new sound file -- then the process moves ahead one sample, repeats, and is added in to the new signal but offset by one sample. In this way, each sample from the musical passage will be treated as if it had been played in the room.
here is an example of code that could realize this process:
//loop to increment through the samples in the first file
for (i=0; i<numsamps1; i++)
{
//loop to increment through the samples in the second file
for(j=0; j<numsamps2; j++)
{
//temp[j] stores the results of each round of computations
temp[j]=amp1[i]*amp2[j];
}
//add each round in to the total
totalsamps=numsamps1+numsamps2-1;
for(x=0; x<totalsamps; x++)
{
conv[x]+=temp[x];
}
}
or, here is a more efficient method:
for (i=0; i<n; i++)
{
for(j=0; i<m; j++)
{
//the output at 'n' is equal to the sum of the
//multiplication of the value at file1[n] and
//the value(s) at file2[0] through file2[m-1]
y[i+j]=y[i+j]+x[i]*h[j];
}
}
At any rate, you don't really have to understand the formula to be able to use convolution in csound, so don't be discouraged if this doesn't make sense right away.
Convolution in Csound
To do convolution in Csound, you will need to use the command-line utility cvanal. In OS X, you can run this from the Terminal window, if you have the command-line version of Csound installed.
Csound requires two different types of files for convolution: one .aif file, and one.con file, which is created using the cvanal utility.
To use the utility, type (in Terminal)
csound -U cvanal inputfile.aif outputfile.con
you will need to either be in the directory of the .aif file you are analyzing, or you will need to tell csound where to find the file. Also, if you do not specify a location for the output file, it will be created in your current directory.
If you are not comfortable using the Terminal, check out http://www.osxfaq.com/Tutorials/LearningCenter/UnixTutorials/LoseTheMouse/index.ws as a good reference for getting your feet wet.
So, for instance, say I have a file titled impulseresponse.aif, and I want to run the cvanal utility, I would move to the directory it is in, then type
csound -U cvanal impulseresponse.aif impulseresponse.con
you can ask for the output file to be named whatever you would like; it is a useful convention to name your .con files for their source .aif file, makes it easier to remember where they've come from.
Now we're ready to do some useful convolution in csound.
You should know that it is possible to do hard-coded convolution in csound, where you manually code the values for one of the files you want to use -- this is horribly inefficient, and I'm not going to go over it. Instead, we're going to skip to the useful way, which is the one that uses these .con files instead.
here is an example of a csound instrument, with .orc and .sco files:
.orc file
instr 2602 ; FFT CONVOLUTION
a1 soundin "fox.aif" ; SIGNAL A
a2 convolve a1,"highpass1k.con" ; SIGNAL B, (USE CVANAL TO MAKE)
out a2*p4 ; P4 IS SCALING FACTOR
endin
.sco file
i 2602 0 3 1
Csound uses the Fast Fourier Transform, or FFT, to make its calculations more efficient. Basically, the Fourier Transform is a reduction of a given segment of sound into its component sine frequencies, with measurements taken of their relative strength and phase. This is a bit of a complicated business, but it is very useful because it means that we can do convolution without having to go sample by sample.
If you want to know more about FFTs, check out http://astronomy.swin.edu.au/~pbourke/analysis/dft/ .
Anyhow, back to Csound. From the .orc file above we can see that csound wants the following:
"instr" instrumentname
a-rate variable 1 "soundin" file1.aif
a-rate variable 2 "convolve" file2.con
out a-rate variable 2 * a scaling factor (you'll be wanting to scale it _down_)
then we need to call the instrument we've created, in our .sco file.
i instrumentname starttime endtime scalingfactor
Now, you don't have to create a variable to scale your output by; it's simply a way to make the instrument more flexible. For instance, this way you could call the instrument several times, and change the scaling factor for each independantly.
This is how to do convolution in Csound.
Experiment with convolving different files together -- you can get some interesting results by convolving two distinctly different sounds.
One thing to note is that for each convolution you do, there will be silence for (I think) the duration of your .con file at the beginning of your output file. You will want to make sure that the duration of your output is at least as long as the combined length of both of your input files, or your output will get cut off.
Have fun !