Wednesday 2 March 2011

Sound synthesis and Fourier analysis

Computer music blog 2:


This week I started to look at how SuperCollider can be used for sound synthesis. I began by booting the internal server. The internal server was used in order to create oscilloscope views of the synthesized sounds. I used online course tutorial material to get started.

I used:


FreqScope.new


This uses Lance Putnam’s frequency scope which is useful for visually plotting the spectrum of sounds explored.

I quickly recapped UGens and the fact that Super Collider uses them as building blocks connecting them together to create synthesizers and sound processors. Ugens have inputs and outputs though most UGens have just one output. After some practice I expect to get to know typical parameter values and inputs/outputs for different UGens.


I started to learn about Subtractive synthesis. This is where you start with a complex sound and subtract parts from it in order to sculpt a different sound.


The course material gives pure white noise as a sound source to subtract from:



{WhiteNoise.ar(0.1)}.scope


and then plugged it into a filter to give a ‘less raw’ sound:


{LPF.ar(WhiteNoise.ar(0.1),1000)}.scope


The LPF cuts out energy above its cutoff frequency which is currently set to 1000hz.


To plug the WhiteNoise UGen into the LPF I need to nest one into the other. The UGens inputs can be thought of as being the list inside the parentheses.


LPF.ar(input, signal, cutoff, frequency..)

If you are unsure about what the inputs are double click on the name of the UGen and press cmd+d which will bring up a help file showing you.


In our previous example we plugged the white noise generator in to the lower pass filter. This is therefore the input signal and must be the first thing contained inside the brackets. 1000 is therefore the next argument, the cutoff frequency.


I then (still using course material) looked at how to vary the cutoff filter over time. This can be done by using a UGen called a line generator.


Line.kr(10000,1000,10) // take ten seconds to go from 10000 to 1000


Instead of using the previous fixed value of 1000 the Line UGen can be plugged into the place of the second argument in the parentheses:


{LPF.ar(WhiteNoise.ar(0.1),Line.kr(10000,1000,10))}.scope



I tried adjusting the code slightly using a few of the example sources and filters.


I used the Resonz filter rather than LPF:


{Resonz.ar(WhiteNoise.ar(0.1),Line.kr(10000,1000,10))}.scope


The result sounded to me to be less noisy and cut out some of the high and low frequencies.


I tried using a different noise source in place of WhiteNoise. I used

PinkNoise to see what difference that would make:


{LPF.ar(PinkNoise.ar(0.1),Line.kr(10000,1000,10))}.scope


This gave a much less harsh sound than WhiteNoise and also sounded quieter. I looked at the help file to try and find out more about it and found that it:


Generates noise whose spectrum falls off in power by 3 dB per octave.

This gives equal power over the span of each octave.

This version gives 8 octaves of pink noise.”


It also had 2 arguments, mul and add.


I then joined them together and used Resonz as the filter and PinkNoise as the sound source. Together they created a much more tamed sound than the original sound. It was slightly flat sounding at first but as the frequencies changed over the 10 seconds it gave a sound that reminded me of the wash of the sea over a shore heard from a distance.


I was then taught about variables. Values are assigned to variables using the = operator.


For example:

a = 1


then 1 is stored in a.


Variables can be useful in many ways. One way that they are useful is as a syntactical short cut when using them to create the size of an array.


(1..10) would give us an array from 1 to 10. Could use any number and this could save us a lot of time, for example if we wanted a larger array such as (1..100) as we would not need to type it all out.



Letters a-z can be used as variable names but it is best to avoid using letter s. This is a default button and variable s is set to contain something that goes into the internal synthesiser.

Another danger is using global variables. It may have been previously set somewhere in another file and won't work. If you define it using


var n


This makes it a local variable instead of a global variable. Name of this can be anything, could change it to my name rosa and it would still work.



Sawtooth waves:


Saw tooth waves are much richer than SinOsc. They have a bright sound compared to dullness of SinOsc


{Saw.ar(440)*0.1}.play


To make a SinOsc sound like a sawtooth each harmonic needs to be divided by its harmonic number ½ ½ 1/3 ¼ etc


One of the differences will be CPU cost. Can see on the internal server a SinOsc is more than a single sawtooth. This is quicker as less sine waves are added up.


If you wanted to create a sawtooth and needed to know which SinOscs to add up you would need to use Fourier analysis.


Freq scope shows us Fourier analysis.


If we took the sawtooth wave and looked at it using the freq analyser (a little window with green lines that shows the frequencies) we would then have to measure the curve and see harmonics are evenly spaced. This shows the harmonic scale. Where it falls off of the straight line gives the harmonic number.

The reason Fourier analysis works is that you can align it with the period of the wave form, so if the frequency is 440 hz, take a snap shot of a period and do Fourier analysis on that period. Think of it like finding a SinOsc that fits that period.


Say root fundamental is 100hz. 1 seconds worth is a period. If 100hz fits 100 times into a second the width is 100th of a second.


This fits exactly on the plot. If this is compared with 100 hz sine wave, then 200 hz sine wave, 3 should fit exactly. The signal then correlates like a sawtooth, falling into a diagonal-ish line. When complex wave forms are broken up in terms of sines then that is Fourier analysis.


Some of the oscillators you can get hold of in SC are packed complex recipes. There is already a sawtooth UGen so don’t need to worry about making one. If you wanted to make your own one you would make a wavetable


Wavetable is one period of a waveform drawn out. It is like sampling but only with a single period not long sound files. If SinOsc hass 5 cycles SC can store shape of single sin cycle and keep repeating it.


Fourier analysis

I decided to do some more reading up on Fourier analysis in order to get a better understanding of it.


The Fourier transform decomposes a signal onto a basis of sinusoids. Given the frequency for a sinusoid, the analysis compares the input signal with both a pure sine and a pure cosine wave of this frequency. This determines an amplitude and phase that indicates how well the input matches the basis element”. Nick Collins, Introduction to Computer Music.


The first line of that quote explains the basic point of Fourier analysis. I read some more to see how this happens.


DFT stands for Discrete Fourier Transform. Sounds vary in their state over time, they can constantly change frequency rather than staying stationary. In order to analyse this changing signal and break it into sinusoids we must take a series of snapshots of the signal. Snapshots are better known as 'windows'. Windows are a number of samples long and each window is treated with a new DFT. Once in a snapshot, the signal is considered to be stationary. Windows can overlap one another but they are usually spaced evenly in time and are the same size.


FFT stands for Fast Fourier Transform. It is an algorithm that speeds up the process of DFT. Each FFT gives a FFT frame of spectral data.


A sequence of DFT's is carried out meaning that every sample appears in a window. This is called STFT (Short Term Fourier Transform). To do this a basic analysis frequency must be set. This is done by using the fundamental frequency corresponding to the period of the wave form. A problem occurs when we do not already know what this fundamental frequency is already. Other problems are if the signal contains a mixture of different periodic sounds or if the sound is inharmonic.


It is possible to try to analyse non periodic sounds using Fourier analysis. A large period which corresponds to a small fundamental frequency can be used. You have to hope the large period is larger than the component frequencies of the sound you are measuring. The Fourier measures the energy from multiples of the fundamental frequency. If we have a low enough fundamental frequency then we it is able to get actual practical use out of the harmonic multiples.


There can also be problems with parts of the frequency 'falling between the gaps' when analysing. The signal could be distributed through the analysis harmonics to give us an indirect perception of the spectrum of the sound.


Consider a sampling rate R of 44 100 Hz, and a segment of duration one second, which as a period corresponds to a frequency of 1 Hz. If this were the basis for Fourier analysis, we would measure at frequency multiples of 1 Hz, so at 1 Hz, 2 Hz, 3 Hz, … all the way up to … the Nyquist frequency of 22 050. Each harmonic of 1 Hz is called a frequency bin or band of the transform” Nick Collins, Introduction to Computer Music.


This helped me to understand the frequency analysis we did in class when looking at curves on the frequency analyser and how Fourier analysis actually used to analyse periods of a wave.


I also found that different types of windows that can be used with Fourier analysis which are often named by their creators such as Hann, Hamming or Kaiser Bessel. They are used for putting the signal into segments. Using different windows can affect the focus on the peak location on the spectrum as well as affecting the amount of spillage between spectral bins. The most popular windows are Hann and Kaiser Bessel windows.











No comments:

Post a Comment