Sunday 19 October 2014

Not Just A Saw Tooth - Generative Complex, Realistic Sounds

The waveform

The common literature on synthesis talks of sawtooth, triangle and square waves. Real sounds are not like this so why do we even discuss them?

Above is the wave form of the first note from my synthesis of BWV 659:


It does not look much like a sawtooth does it? Indeed, that 'presence of God" massive G1 is nothing like any geometrical waveform you will find in any text book or on the front panel of any regular synthesiser.

Spectrum Visualisation

Spectrum Analysis
Interesting sounds have harmonics (partials etc) which move in phase constantly. The pitch the notes are unstable and shifting. The pitch and harmonic content changes though out the note. On top of all of this, they have noise in different colours.

Below are some parts of the code used to create the G1. The final envelope and filter stuff is missing. I am not putting it here to be definitive but to point some stuff out. Like, for example, the additive oscillator bank. Note that to generate just the basic tone I am using 19 'oscillators'. They have random phases each time they are run and they make a harmonic progression with even harmonics begin 180 degrees out of phase with odd ones.

     p1=random.random()
     p2=1.0-p1
...
       sig=sf.Mix(
            sf.PhasedSineWave(length,frequency,p1),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*2.0,p1),2.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*3.0,p2),2.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*4.0,p1),1.8),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*5.0,p2),1.6),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*6.0,p1),1.4),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*7.0,p2),1.2),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*8.0,p1),1.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*9.0,p2),0.8),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*10.0,p1),0.6),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*11.0,p2),0.5),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*12.0,p1),0.4),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*13.0,p2),0.3),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*14.0,p1),0.2),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*15.0,p2),0.1),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*16.0,p1),0.05),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*16.0,p2),0.05),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*17.0,p1),0.05),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*18.0,p2),0.05),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*19.0,p1),0.01)
        )
    sig=sf.Multiply(
        sf.NumericShape((0,0),(32,1),(length,1)),
        sig
    )
...
    b=posaunePulse(length,freq)
    b=sf.MixAt(
        [b,12],
        [
        sf.NumericShape(
            (0, -2.0),
            (4,  2.0),
            (12,-1.00),
            (20, 1.00),
            (28,-1.00),
            (length,0)
        ),0]
    )
    b=sf.RBJPeaking(b,freq*2,2,2)
    b=polish(b,freq)
    sig=sf.Mix(
        b
        ,
        sf.Pcnt20(sf.Multiply(+b,sf.WhiteNoise(length))),          
        sf.Multiply(
            cleanNoise(length,freq*0.5),
            sf.SimpleShape((0,-60),(64,-14),(128,-28),(length,-24))
        )
    )

    return pitchMove(sig)
...
def pitchMove(sig):
    l=sf.Length(+sig)
    if l>1024:
        move=sf.NumericShape(
            (0,0.995+random.random()*0.01),
            (l,0.995+random.random()*0.01)
        )
    elif l>512:
        move=sf.NumericShape(
            (0,0.9975+random.random()*0.005),
            (l,0.9975+random.random()*0.005)
        )
    else:
        return sig

    return sf.Clean(sf.Resample(move,sig))

Next I mix in a 'clunk' sound to model the valve of the pipe opening. This is done using an envelope and a low pass filter. I throw in a resonant all pass filter and a filter to remove aliasing. The signal ins ring modulated (multiplied by) filtered white noise to mimic the sound of air rushing over the reed. Some enveloped white noise is added as well.

Finally, the pitch of the note is made to move slightly throughout its sounding. Actually, this is (as I said) not the whole story as there is another section which applies filtering, and a volume envelope which is also used to very slightly frequency modulate the sound to mimic the way real pitch changes with volume. The envelope applied here is not only dependant on the length of the note but on the length and proximity of the notes either side of it.

The sound you hear is actually three pipes. Each with very, very slightly differently out of tune, sounding three octaves (G1, G0 and G-1). But that is not all as the three are then places at slightly different times to one another and with respect too the left and right channels.

Then some harmonic excitement and filtering and two different impulse response reverberations are applied.

All that is what is required to make that one, single note.

A far cry from 'what does a saw tooth sound like'.

No comments:

Post a Comment