Thursday 2 October 2014

Stopped Reed: Warm To Sparkling

I don't actually know if anyone produces stopped reed pipes. In truth, it is not really necessary as a cylindrical bore read would make much the same sound. Anyhow - it was a sound I had in my head so here is how I tried to make it:


def stoppedPulse(length,frequency):
    p=random.random()
    if frequency>3000:
        sig=sf.Mix(
            sf.PhasedSineWave(length,frequency,p),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*3.0,p),1.0/1.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*5.0,p),1.0/1.5),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*7.0,p),1.0/2.0)
            )
    else:
        sig=sf.Mix(
            sf.PhasedSineWave(length,frequency,p),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*3.0,p),1.0/1.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*5.0,p),1.0/1.5),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*7.0,p),1.0/2.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*9.0,p),1.0/4.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*11.0,p),1.0/8.0)
        )
    return sf.FixSize(sig)

def stoppedReed(length,freq):
    s1=stoppedPulse(length,freq*1.000)
    s1=sf.ButterworthHighPass(s1,freq*0.66,6)
    s1=sf.Clean(s1)
    
    sig=sf.Mix(
        s1,
        sf.Multiply(
            cleanNoise(length,freq*2.0),
            sf.SimpleShape((0,-60),(64,-16),(128,-20),(length,-20))
        )
    )

    sig=sf.FixSize(sig)
    sig=sf.Mix(
        sf.Pcnt10(sf.Clean(sf.Saturate(+sig))),
        sig
    )
    sig=sf.ButterworthHighPass(sig,freq*0.66,6)
    sig=sf.Clean(sig)

    return sf.FixSize(sf.Clean(sig))

The voice is simple enough, it takes a clean sound from additive synthesis, adds some enveloped, filtered white noise and makes sure no nasty aliasing artefacts sneak in. To brighten it up a little, I have added a touch of sf.Saturate. This tends to add mainly odd harmonics anyhow - so it is a good way to add some colour to what was otherwise rather sterile.

Normally, we might try to make the 'odd harmonic only' sound of a stopped pipe or a cylindrical read (think clarinet) sound using square waves. I did not do this. The waves I used have a much larger contributions from the early harmonics and stop short to ensure no aliasing happens.

        sig=sf.Mix(
            sf.PhasedSineWave(length,frequency,p),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*3.0,p),1.0/1.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*5.0,p),1.0/1.5),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*7.0,p),1.0/2.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*9.0,p),1.0/4.0),
            sf.NumericVolume(sf.PhasedSineWave(length,frequency*11.0,p),1.0/8.0)
        )

 Here we can see that I am adding only odd harmonics but that the third is actually great a magnitude as the fundamental and that the harmonics die away slowly. This gives a more reed sound; something brighter and potentially more harsh. However, in the later stages of processing filtering takes some of these higher harmonics back down. (note that for this sound, the subBass granular processing is turned off).

        if pitch<256:
            if subBass:
                if pitch < 128:
                    sig=sf.Mix(
                        granularReverb(+sig,ratio=0.501 ,delay=256,density=32,length=256,stretch=1,vol=0.20),
                        granularReverb(+sig,ratio=0.2495,delay=256,density=32,length=256,stretch=1,vol=0.10),
                        sig
                    )
                elif pitch < 192:
                    sig=sf.Mix(
                        granularReverb(+sig,ratio=0.501,delay=256,density=32,length=256,stretch=1,vol=0.25),
                        sig
                    )
                else:
                    sig=sf.Mix(
                        granularReverb(+sig,ratio=0.501,delay=256,density=32,length=256,stretch=1,vol=0.15),
                        sig
                    )
            sig=sf.BesselLowPass(sig,pitch*8.0,2)
        if pitch<392:
            sig=sf.BesselLowPass(sig,pitch*6.0,2)
        elif pitch<512:
            sig=sf.Mix(
                sf.BesselLowPass(+sig,pitch*6.0, 2),
                sf.BesselLowPass( sig,pitch*3.0, 2)
            )                
        elif pitch<640:
            sig=sf.BesselLowPass(sig,pitch*3.5, 2)
        elif pitch<1280:
            sig=sf.Mix(
                sf.BesselLowPass(+sig,pitch*3.5, 2),
                sf.BesselLowPass( sig,pitch*5.0, 2)
            )                
        else:
            sig=sf.Mix(
                sf.BesselLowPass(+sig,pitch*5, 2),
                sf.BesselLowPass( sig,5000,    1)
            )


That combination give rich, warm low tones and bright sparkling high notes. I am really taken with the effect even it I do say so myself. In this video the upper two voices are both generated using this voice:


No comments:

Post a Comment