Thursday, 21 August 2014
Thursday, 14 August 2014
Code Behind Cold
import random import math sf.SetSampleRate(192000) # Single threaded for debug #def sf_do(toDo): # return toDo() def granularReverb(signal,ratio,delay): def granularReverbInner(): out=[] for grain in sf.Granulate(signal,50,10): (signal_i,at)=grain signal_i=sf.DirectRelength(signal_i,ratio-0.01+(0.02*random.random())) for x in range(0,50): out.append( ( +signal_i, at + (random.random()+random.random())*delay ) ) -signal_i return sf.Normalise(sf.MixAt(out)) return sf_do(granularReverbInner) def reverbInner(signal,convol,grainLength): def reverbInnerDo(): mag=sf.Magnitude(+signal) if mag>0: signal_=sf.Concatenate(signal,sf.Silence(grainLength)) signal_=sf.FrequencyDomain(signal_) signal_=sf.CrossMultiply(convol,signal_) signal_=sf.TimeDomain(signal_) newMag=sf.Magnitude(+signal_) signal_=sf.NumericVolume(signal_,mag/newMag) # tail out clicks due to amplitude at end of signal return signal_ else: -convol return signal return sf_do(reverbInnerDo) def reverberate(signal,convol): def reverberateDo(): grainLength = sf.Length(+convol) convol_=sf.FrequencyDomain(sf.Concatenate(convol,sf.Silence(grainLength))) signal_=sf.Concatenate(signal,sf.Silence(grainLength)) out=[] for grain in sf.Granulate(signal_,grainLength): (signal_i,at)=grain out.append((reverbInner(signal_i,+convol_,grainLength),at)) -convol_ return sf.Realise(sf.Normalise(sf.MixAt(out))) return sf_do(reverberateDo) # Get IRs violinIRs = sf.ViolinBodyIRs(()) #violaIRs = sf.ViolaBodyIRs(()) celloIRs = sf.CelloBodyIRs(()) bassIRs = sf.BassBodyIRs(()) def createSawTooth(length,pitch): signals=[] v=1 opitch=pitch it=1.0 phase=random.random() while pitch<18000: signals.append(sf.NumericVolume(sf.PhasedSineWave(length,pitch,phase),1.0/it)) pitch+=opitch it+=1 return sf.Clean(sf.FixSize(sf.Mix(signals))) def rawString(length,pitch): def rawStringA(l,p): def rawStringAIn(): return createSawTooth(l,p) return sf_do(rawStringAIn) pitch=float(pitch) #pitch=pitch+pitch*random.random()*0.0001 s1=rawStringA(length,pitch) s2=rawStringA(length,pitch*2.0) s3=rawStringA(length,pitch*4.0) s4=sf.WhiteNoise(length) signal=sf.Normalise( sf.Mix( sf.Pcnt20(s4), sf.Pcnt50(s1), sf.Pcnt20(s2), sf.Pcnt10(s3) ) ) signal=sf.Clean(sf.ResonantFilter(signal,0.95,0.15,sf.Period(pitch))) multi=sf.Normalise( sf.DirectRelength( sf.ButterworthLowPass(sf.WhiteNoise(length/500.0),2500,6), 0.001 ) ) multi=sf.Cut(0,sf.Length(+signal),multi) signal=sf.Resample( sf.DirectMix(1,sf.NumericVolume(multi,0.001)), signal ) return sf.Realise(sf.Normalise(sf.Clean(signal))) def playStringClean(a,length,pitch,whiteAmount): def rsd(): return rawString(length,pitch) signal=0 if(pitch>500): signal=sf.Normalise(sf.Mix(sf_do(rsd),sf_do(rsd),sf_do(rsd))) else: signal=sf.Normalise(sf.Mix(sf_do(rsd),sf_do(rsd))) if(pitch>440): signal=sf.ButterworthHighPass(signal,pitch*0.5,6) signal=sf.ButterworthHighPass(signal,2000,1) signal=sf.ButterworthLowPass(signal,8000,1) if(pitch<128): signal=sf.ButterworthHighPass(signal,pitch*0.5,1) signal=sf.ButterworthHighPass(signal,500,1) signal=sf.ButterworthLowPass(signal,2000,1) else: signal=sf.ButterworthHighPass(signal,pitch*0.5,3) signal=sf.ButterworthHighPass(signal,1500,1) signal=sf.ButterworthLowPass(signal,4000,1) signal=sf.ButterworthLowPass(signal,pitch*10.0,1) signal=sf.Mix( sf.Pcnt25(+signal), sf.Pcnt75(sf.RBJNotch(signal,pitch,0.5)) ) white=sf.WhiteNoise(length) white=sf.ButterworthHighPass(white,pitch*2.0,2) white=sf.ButterworthLowPass(white,pitch*6.0,1) white=sf.Normalise(white) white=sf.Multiply(white,+signal) white=sf.NumericVolume(white,whiteAmount) signal=sf.NumericVolume(signal,1.0-whiteAmount) signal=sf.Normalise(sf.Mix(signal,white)) sq=sf.Mix( sf.PhasedSineWave(length,pitch*0.95,random.random()), sf.PhasedSineWave(length,pitch*1.05,random.random()) ) envb=sf.NumericShape((0,0.25),(a,0),(length,0)) sq=sf.Multiply(envb,sf.FixSize(sq)) enva=sf.NumericShape((0,0.75),(a,1),(length,1)) signal=sf.Multiply(enva,signal) signal=sf.Mix(sq,sf.FixSize(signal)) sigs=[] bodies=[] if(pitch<128): bodies=bassIRs elif(pitch<440): bodies=celloIRs else: bodies=violinIRs for body in violinIRs: sigs.append(reverberate(+signal,+body)) -signal signal=sf.Normalise(sf.Mix(sigs)) return signal def playString(pitch,e,a,d,dat,s,sat,r,whiteAmount,vibStart,vibMiddle,vibAmount,vibRate=2.0): print ("Performing Note: ",pitch,e,a,d,dat,s,sat,r,whiteAmount,vibStart,vibMiddle,vibAmount,vibRate) def playStringInner(): envA=sf.SimpleShape( (0,-60), (e,0), (d,0), (s,0), (r,0) ) envB=sf.NumericShape( (0,0), (a,1), (d,dat), (s,sat), (r,0) ) env=sf.Multiply(envA,envB) sigs=[] for x in range(0,5): sigs.append(playStringClean(a,r,pitch,whiteAmount)) signal=sf.Normalise(sf.Mix(sigs)) signal=sf.Multiply(signal,env) if(vibAmount>0): l=sf.Length(+signal) env=sf.NumericShape((0,0),(vibStart,0),(vibMiddle,1),(r,0.75),(l,0)) env=sf.NumericVolume(env,vibAmount) trem=sf.SineWave(l,2.0+random.random()) trem=sf.Multiply(env,trem) vib=+trem trem=sf.DirectMix(1,sf.Pcnt50(trem)) signal=sf.Multiply(trem,signal) vib=sf.DirectMix(1,sf.NumericVolume(vib,0.01)) signal=sf.Resample(vib,signal) if(pitch>128): signal=sf.ButterworthHighPass(signal,pitch*0.75,6) signal=sf.BesselLowPass(signal,pitch,1) else: signal=sf.ButterworthHighPass(signal,pitch*0.75,3) return sf.Realise(sf.Normalise(sf.Clean(signal))) return sf_do(playStringInner) def playStringInitial(pitch,length,volume): def playStringInitialInner(): sig=playString( pitch, 64, # e 128, # a length*0.5, # d 0.75, # d at length*0.75, # s 1.0, # s at length, # r 0.75, # white amount length*0.75, # vib start length*0.75, # vib middle 0.5 # vib amount ) envH=sf.NumericShape((0,1),(length*0.25,0.25),(length,0.25)) envL=sf.NumericShape((0,0),(length*0.25,0.75),(length,0.75)) sig=sig.get() sigLow=sf.ButterworthLowPass(+sig,pitch*2.0,2) sigHi =sf.ButterworthHighPass(sig ,pitch*2.0,2) sigLow=sf.Multiply(sigLow,envL) sigHi =sf.Multiply(sigHi ,envH) env =sf.NumericShape((0,0),(length*0.25,0.25),(length*0.5,1),(length,1)) sig =sf.Mix(sigLow,sigHi) sig =sf.FixSize(sf.Multiply(env,sig)) return sf.Clean(sf.NumericVolume(sig,volume)) return sf_do(playStringInitialInner) def playStringSuperSoft(pitch,length,volume): def playStringSoftSuperInner(): if(pitch<256): w=0.75 else: if(pitch<720): w=0.33 else: w=0.25 sig = sf.NumericVolume( playString( pitch, 64, # e length*0.25, # a length*0.50, # d 1.0, # d at length*0.75, # s 1.0, # s at length, # r w, # white amount length*0.50, # vib start length*0.75, # vib middle 0.5 # vib amount ), volume ) env = sf.NumericShape((0,0),(length*0.25,1),(length,1)) return sf.Clean(sf.FixSize(sf.Multiply(env,sig))) return sf_do(playStringSoftSuperInner) def playStringSoftShort(pitch,length,volume): def playStringSoftShortInner(): if(pitch<256): w=0.5 else: if(pitch<720): w=0.25 else: w=0.15 return sf.Clean(sf.NumericVolume( playString( pitch, 32, # e 64, # a length*0.15, # d 1.0, # d at length*0.5, # s 0.5, # s at length, # r w, # white amount length*0.50, # vib start length*0.75, # vib middle 0.5 # vib amount ), volume )) return sf_do(playStringSoftShortInner) def playStringHardLong(pitch,length,volume): def playStringHardLong(): if(pitch<256): w=0.1 else: if(pitch<720): w=0.1 else: w=0.05 return sf.Clean(sf.NumericVolume( playString( pitch, 32, # e 64, # a length*0.25, # d 1.0, # d at length*0.75, # s 0.75, # s at length, # r w, # white amount length*0.25, # vib start length*0.75, # vib middle 0.5 # vib amount - no vib in this case ), volume )) return sf_do(playStringHardLong) def playStringHardShort(pitch,length,volume): def playStringHardShortInner(): if(pitch<256): w=0.1 else: if(pitch<720): w=0.1 else: w=0.05 return sf.Clean(sf.NumericVolume( playString( pitch, 32, # e 64, # a length*0.125, # d 1.0, # d at length*0.75, # s 0.75, # s at length, # r w, # white amount length*0.25, # vib start length*0.75, # vib middle 0 # vib amount - no vib in this case ), volume )) return sf_do(playStringHardShortInner) def playStringPluck(pitch,length,volume): def playStringPluckInner(): sig=playString( pitch, 8, # e 16, # a 32, # d 0.5, # d at length*0.75, # s 0.25, # s at length, # r 0, # white amount length*0.50, # vib start length*0.90, # vib middle 1 # vib amount - no vib in this case ) envH=sf.NumericShape((0,0),(32,1),(length,0)) envL=sf.NumericShape((0,1),(32,0),(length,1)) sig=sig.get() sigL=sf.ButterworthLowPass(+sig,pitch,1) sigL=sf.ButterworthLowPass(sigL,pitch*3,1) sigH=sf.Multiply(sig,envH) sigL=sf.Multiply(sigL,envL) sig=sf.Mix(sigL,sigH) sig=sf.NumericVolume(sig,volume) return sig return sf_do(playStringPluckInner) def makeClick(formant): clickA=sf.Multiply( sf.SimpleShape((0,0),(500,-30),(512,-60)), sf.NumericShape((0,0),(100,1),(-300,-1),(400,0)), sf.FixSize(sf.Power(sf.WhiteNoise(512),8)) ) clickA=sf.BesselLowPass(clickA,440,1) clickA=formant(clickA) for i in range(0,4): clickB=sf.BesselLowPass(+clickA,440,1) clickB=formant(clickB) clickA=sf.MixAt( (clickA,0), (clickB,beat/8) ) return sf.Normalise(clickA) def doFormant(sig,f1,f2,f3): def doFormantInner(a,b,c,d): def doFII(): return sf.RBJPeaking(a,b,c,d) return sf_do(doFII) sig1=doFormantInner(+sig,f1,1,40) sig2=doFormantInner(+sig,f2,2,20) sig3=doFormantInner( sig,f3,1,40) x=sf.Mix(sig1,sig2,sig3) x=sf.Normalise(x) return sf.Realise(x) #beat def doFormant1(sig): return doFormant(sig,300,2800,3300) #bit def doFormant2(sig): return doFormant(sig,430,2500,3100) #bet def doFormant3(sig): return doFormant(sig,600,2350,3000) #bat def doFormant4(sig): return doFormant(sig,860,2050,2850) #part def doFormant5(sig): return doFormant(sig,850,1200,2800) #pot def doFormant6(sig): return doFormant(sig,590,900,2700) #boat def doFormant7(sig): return doFormant(sig,470,1150,2700) #boat def doFormant8(sig): return doFormant(sig,470,1150,2700) #book def doFormant9(sig): return doFormant(sig,370,950,2650) #but def doFormant10(sig): return doFormant(sig,760,1400,2800) #pert def doFormant11(sig): return doFormant(sig,500,1650,1950) # oddness #pert def doFormant12(sig): return doFormant(sig,550,1800,2050) formants=[ doFormant1, doFormant2, doFormant3, doFormant4, doFormant5, doFormant6, doFormant7, doFormant8, doFormant9, doFormant10, doFormant11, doFormant12 ] # Very slow indeed beat = 1024*2.0 def phrase1(): print "Phrase 1" at = 0 sigl = [] sigr = [] pitch=sf.Note("G6") length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 1 at+=beat*1 pitch=sf.Note("G6") pitch+=10 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("G6") length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) at+=beat*0.5 pitch=sf.Note("G6") length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 3 at+=beat*0.5 pitch=sf.Note("G6") length=beat*0.2 sigl.append((playStringPluck(pitch,length,0.25),at)) sigr.append((playStringPluck(pitch,length,0.75),at)) at+=beat*0.25 pitch=sf.Note("G6") pitch+=10 length=beat*0.15 sigl.append((playStringPluck(pitch,length,0.75),at)) sigr.append((playStringPluck(pitch,length,0.25),at)) # 4 at+=beat*0.75 pitch=sf.Note("G6") length=beat*2.0 sigl.append((playStringSoftShort(pitch,length,0.15),at)) sigr.append((playStringSoftShort(pitch,length,0.15),at)) pitch=sf.Note("G7") length=beat*0.15 pitch*=1.01 sigl.append((playStringPluck(pitch,length,0.05),at)) pitch=sf.Note("G7") pitch*=0.99 sigr.append((playStringPluck(pitch,length,0.05),at)) print "Compiling Phrase1" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft = granularReverb(+left,0.5,1000) wright = granularReverb(+right,0.5,1000) left=sf.Normalise(sf.MixAt( (sf.Pcnt50(wleft),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt50(wright),0), (sf.Pcnt50(right),0) )) sf.WriteFile32([left,right],"temp/phrase-1.wav") def phrase2(): print "Phrase 2" at = 0 sigl = [] sigr = [] pitch=sf.Note("G6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 1 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("G6") length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) at+=beat*0.5 pitch=sf.Note("G6") length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 3 at+=beat*0.5 pitch=sf.Note("G6") pitch+=10 length=beat*0.2 sigl.append((playStringPluck(pitch,length,0.75),at)) sigr.append((playStringPluck(pitch,length,0.25),at)) at+=beat*0.25 pitch=sf.Note("G6") length=beat*0.15 sigl.append((playStringPluck(pitch,length,0.25),at)) sigr.append((playStringPluck(pitch,length,0.75),at)) # 4 at+=beat*0.75 pitch=sf.Note("F6") length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) print "Compiling Phrase2" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft = granularReverb(+left,0.5,1000) wright = granularReverb(+right,0.5,1000) left=sf.Normalise(sf.MixAt( (sf.Pcnt50(wleft),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt50(wright),0), (sf.Pcnt50(right),0) )) sf.WriteFile32([left,right],"temp/phrase-2.wav") def phrase3(): print "Phrase 3" at = 0 sigl = [] sigr = [] pitch=sf.Note("F6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 1 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("F6") length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) at+=beat*0.5 pitch=sf.Note("F6") length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 3 at+=beat*0.5 pitch=sf.Note("F6") pitch+=10 length=beat*0.2 sigl.append((playStringPluck(pitch,length,0.75),at)) sigr.append((playStringPluck(pitch,length,0.25),at)) at+=beat*0.25 pitch=sf.Note("G6") length=beat*0.15 sigl.append((playStringPluck(pitch,length,0.25),at)) sigr.append((playStringPluck(pitch,length,0.75),at)) # 4 at+=beat*0.75 pitch=sf.Note("A6") length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) print "Compiling Phrase3" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft = granularReverb(+left,0.5,1000) wright = granularReverb(+right,0.5,1000) left=sf.Normalise(sf.MixAt( (sf.Pcnt50(wleft),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt50(wright),0), (sf.Pcnt50(right),0) )) sf.WriteFile32([left,right],"temp/phrase-3.wav") def phrase4(): print "Phrase 4" at = 0 sigl = [] sigr = [] pitch=sf.Note("A6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 1 at+=beat*1 pitch=sf.Note("B6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 3 at+=beat*1 pitch=sf.Note("A6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 4 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 5 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) print "Compiling Phrase4" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,1000) wright1 = granularReverb(+right,0.5,1000) wleft2 = granularReverb(+left,0.75,1200) wright2 = granularReverb(+right,0.75,1200) left=sf.Normalise(sf.MixAt( (sf.Pcnt40(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt30(wright2),0), (sf.Pcnt50(right),0) )) sf.WriteFile32([left,right],"temp/phrase-4.wav") def phrase5(): print "Phrase 5" at = 0 sigl = [] sigr = [] pitch=sf.Note("G0") pitch+=10 length=beat*3 sigl.append((playStringSuperSoft(pitch,length,0.5),at)) sigr.append((playStringSuperSoft(pitch,length,0.5),at)) # 1 at+=beat*3 pitch=sf.Note("D1") sigl.append((playStringSuperSoft(pitch,length,0.5),at)) sigr.append((playStringSuperSoft(pitch,length,0.5),at)) print "Compiling Phrase4" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left, 0.5,1000) wright1 = granularReverb(+right,0.5,1000) wleft2 = granularReverb(+left, 1.5,1200) wright2 = granularReverb(+right,1.5,1200) #6 -> #3 : boat to bat left=sf.Normalise(sf.MixAt( (sf.Pcnt40(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt30(wright2),0), (sf.Pcnt50(right),0) )) def doBoatBat(sig): l=sf.Length(+sig) envBoat=sf.NumericShape((0,1),(l,0)) sigBoat=sf.Multiply(envBoat,+sig) sigBoat=doFormant6(+sig) envBat =sf.NumericShape((0,0),(l,1)) sigBat =sf.Multiply(envBat,+sig) sigBat =doFormant3(sig) sig =sf.Mix(sigBat,sigBoat) return sf.Normalise(sf.ButterworthLowPass(sig,256,1)) left = doBoatBat(left) right= doBoatBat(right) sf.WriteFile32([left,right],"temp/phrase-5.wav") def phrase6(): print "Phrase 6" at = 0 sigl = [] sigr = [] pitch=sf.Note("A6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) # 1 at+=beat*1 pitch=sf.Note("B6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) # 3 at+=beat*1 pitch=sf.Note("A6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 4 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) # 5 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 6 at+=beat*1 pitch=sf.Note("D6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) print "Compiling Phrase6" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,800) wright1 = granularReverb(+right,0.5,8000) wleft2 = granularReverb(+left,0.25,1500) wright2 = granularReverb(+right,0.25,1500) left=sf.Normalise(sf.MixAt( (sf.Pcnt40(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt30(wright2),0), (sf.Pcnt50(right),0) )) sf.WriteFile32([left,right],"temp/phrase-6.wav") def phrase7(): print "Phrase 7" at = 0 sigl = [] sigr = [] pitch=sf.Note("A6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 1 at+=beat*1 pitch=sf.Note("B6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 3 at+=beat*1 pitch=sf.Note("A6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 4 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 5 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 6 at+=beat*1 pitch=sf.Note("D6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) print "Compiling Phrase7" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,800) wright1 = granularReverb(+right,0.5,800) wleft2 = granularReverb(+left,0.25,1500) wright2 = granularReverb(+right,0.25,1500) r=0.5*6.0/5.0 wleft3 = granularReverb(+left ,r,1000) wright3 = granularReverb(+right,r,1000) left=sf.Normalise(sf.MixAt( (sf.Pcnt30(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt10(wleft3),0), (sf.Pcnt50(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt20(wright2),0), (sf.Pcnt20(wright3),0), (sf.Pcnt40(right),0) )) sf.WriteFile32([left,right],"temp/phrase-7.wav") def phrase8(): print "Phrase 8" at = 0 sigl = [] sigr = [] pitch=sf.Note("G6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 1 at+=beat*1 pitch=sf.Note("A6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 3 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 4 at+=beat*1 pitch=sf.Note("E6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 5 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 6 at+=beat*1 pitch=sf.Note("C6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) print "Compiling Phrase8" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,800) wright1 = granularReverb(+right,0.5,800) wleft2 = granularReverb(+left,0.25,1500) wright2 = granularReverb(+right,0.25,1500) r=0.5*6.0/5.0 wleft3 = granularReverb(+left ,r,1000) wright3 = granularReverb(+right,r,1000) wleft4 = granularReverb(+left,1.5,2000) wright4 = granularReverb(+right,1.5,2000) left=sf.Normalise(sf.MixAt( (sf.Pcnt30(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt10(wleft3),0), (sf.Pcnt5(wleft4),0) , (sf.Pcnt45(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt20(wright2),0), (sf.Pcnt20(wright3),0), (sf.Pcnt5(wright4),0) , (sf.Pcnt35(right),0) )) sf.WriteFile32([left,right],"temp/phrase-8.wav") def phrase9(): print "Phrase 9" at = 0 sigl = [] sigr = [] pitch=sf.Note("F6") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 1 at+=beat*1 pitch=sf.Note("G6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("E6b") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 3 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 4 at+=beat*1 pitch=sf.Note("D6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 5 at+=beat*1 pitch=sf.Note("E6b") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 6 at+=beat*1 pitch=sf.Note("B5b") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) print "Compiling Phrase9" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,800) wright1 = granularReverb(+right,0.5,800) wleft2 = granularReverb(+left,0.25,1500) wright2 = granularReverb(+right,0.25,1500) r=0.5*6.0/5.0 wleft3 = granularReverb(+left ,r,1000) wright3 = granularReverb(+right,r,1000) wleft4 = granularReverb(+left,1.5,2000) wright4 = granularReverb(+right,1.5,2000) left=sf.Normalise(sf.MixAt( (sf.Pcnt30(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt10(wleft3),0), (sf.Pcnt5(wleft4),0) , (sf.Pcnt45(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt20(wright2),0), (sf.Pcnt20(wright3),0), (sf.Pcnt5(wright4),0) , (sf.Pcnt35(right),0) )) sf.WriteFile32([left,right],"temp/phrase-9.wav") def phrase10(): print "Phrase 10" at = 0 sigl = [] sigr = [] pitch=sf.Note("E6b") pitch+=10 length=beat*0.5 sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 1 at+=beat*1 pitch=sf.Note("F6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 2 at+=beat*1 pitch=sf.Note("D6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 3 at+=beat*1 pitch=sf.Note("E6b") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 4 at+=beat*1 pitch=sf.Note("C6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) # 5 at+=beat*1 pitch=sf.Note("D6") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) # 6 at+=beat*1 pitch=sf.Note("A5") sigl.append((playStringPluck(pitch,length,0.5),at)) sigr.append((playStringPluck(pitch,length,0.5),at)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.25)) pitch*=2 length=beat*0.25 sigl.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) sigr.append((playStringPluck(pitch,length,0.15),at+beat*0.50)) print "Compiling Phrase10" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,800) wright1 = granularReverb(+right,0.5,800) wleft2 = granularReverb(+left,0.25,1500) wright2 = granularReverb(+right,0.25,1500) r=0.5*6.0/5.0 wleft3 = granularReverb(+left ,r,1000) wright3 = granularReverb(+right,r,1000) wleft4 = granularReverb(+left,1.5,2000) wright4 = granularReverb(+right,1.5,2000) left=sf.Normalise(sf.MixAt( (sf.Pcnt30(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt10(wleft3),0), (sf.Pcnt5(wleft4),0) , (sf.Pcnt45(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt20(wright1),0), (sf.Pcnt20(wright2),0), (sf.Pcnt20(wright3),0), (sf.Pcnt5(wright4),0) , (sf.Pcnt35(right),0) )) sf.WriteFile32([left,right],"temp/phrase-10.wav") def phrase11(): print "Phrase 11" at = 0 sigl = [] sigr = [] pitch=sf.Note("G6") pitch+=10 length=beat*4.0 sigl.append((playStringSuperSoft(pitch,length,0.5),at)) sigr.append((playStringSuperSoft(pitch,length,0.5),at)) print "Compiling Phrase11" left=sf.FixSize(sf.MixAt(sigl)) right=sf.FixSize(sf.MixAt(sigr)) wleft1 = granularReverb(+left,0.5,800) wright1 = granularReverb(+right,0.5,800) wleft2 = granularReverb(+left,0.25,2400) wright2 = granularReverb(+right,0.25,2400) r=0.5*6.0/5.0 wleft3 = granularReverb(+left ,r,1600) wright3 = granularReverb(+right,r,1600) wleft4 = granularReverb(+left,0.125,3200) wright4 = granularReverb(+right,0.125,3200) wleft5 = granularReverb(+left,0.0625,3800) wright5 = granularReverb(+right,0.0625,3800) wleft5 = granularReverb(wleft5,1.0,3800) wright5 = granularReverb(wright5,1.0,3800) left=sf.Normalise(sf.MixAt( (sf.Pcnt10(wleft1),0), (sf.Pcnt10(wleft2),0), (sf.Pcnt10(wleft3),0), (sf.Pcnt20(wleft4),0) , (sf.Pcnt20(wleft5),0) , (sf.Pcnt30(left),0) )) right=sf.Normalise(sf.MixAt( (sf.Pcnt10(wright1),0), (sf.Pcnt10(wright2),0), (sf.Pcnt10(wright3),0), (sf.Pcnt20(wright4),0) , (sf.Pcnt20(wright5),0) , (sf.Pcnt30(right),0) )) sf.WriteFile32([left,right],"temp/phrase-11.wav") #phrase1() #phrase2() #phrase3() #phrase4() #phrase5() #phrase6() #phrase7() #phrase8() #phrase9() #phrase10() phrase11() (left1,right1)=sf.ReadFile("temp/phrase-1.wav") left1 = sf.Swap(left1) right1 = sf.Swap(right1) (left2,right2)=sf.ReadFile("temp/phrase-2.wav") left2 = sf.Swap(left2) right2 = sf.Swap(right2) (left3,right3)=sf.ReadFile("temp/phrase-3.wav") left3 = sf.Swap(left3) right3 = sf.Swap(right3) (left4,right4)=sf.ReadFile("temp/phrase-4.wav") left4 = sf.Swap(left4) right4 = sf.Swap(right4) (left5,right5)=sf.ReadFile("temp/phrase-5.wav") left5 = sf.Swap(left5) right5 = sf.Swap(right5) (left6,right6)=sf.ReadFile("temp/phrase-6.wav") left6 = sf.Swap(left6) right6 = sf.Swap(right6) (left7,right7)=sf.ReadFile("temp/phrase-7.wav") left7 = sf.Swap(left7) right7 = sf.Swap(right7) (left8,right8)=sf.ReadFile("temp/phrase-8.wav") left8 = sf.Swap(left8) right8 = sf.Swap(right8) (left9,right9)=sf.ReadFile("temp/phrase-9.wav") left9 = sf.Swap(left9) right9 = sf.Swap(right9) (left10,right10)=sf.ReadFile("temp/phrase-10.wav") left10 = sf.Swap(left10) right10 = sf.Swap(right10) (left11,right11)=sf.ReadFile("temp/phrase-11.wav") left11 = sf.Swap(left11) right11 = sf.Swap(right11) left = sf.FixSize( sf.MixAt( ( sf.Pcnt50( left1),1000), ( sf.Pcnt50(+left2),1000+beat*6), ( sf.Pcnt50( left3),1000+beat*12), ( sf.Pcnt50(+left4),1000+beat*18), ( sf.Pcnt50( left2),1000+beat*24), ( sf.Pcnt40(+left5),1000+beat*29), ( sf.Pcnt20( left4),1000+beat*30), ( sf.Pcnt20(+left6),1000+beat*36), ( sf.Pcnt40(+left5),1000+beat*35), ( sf.Pcnt40(+left7),1000+beat*42), # 8 time ( sf.Pcnt20(+left5),1000+beat*41), ( sf.Pcnt20(+left8),1000+beat*50), ( sf.Pcnt40(+left5),1000+beat*49), ( sf.Pcnt40(+left9),1000+beat*58), ( sf.Pcnt20(+left5),1000+beat*57), ( sf.Pcnt20(+left10),1000+beat*66), ( sf.Pcnt40(+left5) ,1000+beat*65), ( sf.Pcnt40( left7),1000+beat*74), ( sf.Pcnt20(+left5),1000+beat*73), ( sf.Pcnt20( left8),1000+beat*82), ( sf.Pcnt40(+left5),1000+beat*81), ( sf.Pcnt40( left9),1000+beat*90), ( sf.Pcnt20(+left5),1000+beat*89), ( sf.Pcnt20( left10),1000+beat*98), ( sf.Pcnt40( left5) ,1000+beat*97), ( sf.Pcnt50( left11),1000+beat*106) ) ) right = sf.FixSize( sf.MixAt( ( sf.Pcnt50( right1),1000), ( sf.Pcnt50(+right2),1000+beat*6), ( sf.Pcnt50( right3),1000+beat*12), ( sf.Pcnt50(+right4),1000+beat*18), ( sf.Pcnt50( right2),1000+beat*24), ( sf.Pcnt20(+right4),1000+beat*30), ( sf.Pcnt40(+right5),1000+beat*29), ( sf.Pcnt40( right6),1000+beat*36), ( sf.Pcnt20(+right5),1000+beat*35), ( sf.Pcnt20(+right7),1000+beat*42), # 8 time ( sf.Pcnt40(+right5),1000+beat*41), ( sf.Pcnt40(+right8),1000+beat*50), ( sf.Pcnt20(+right5),1000+beat*49), ( sf.Pcnt20(+right9),1000+beat*58), ( sf.Pcnt40(+right5),1000+beat*57), ( sf.Pcnt40(+right10),1000+beat*66), ( sf.Pcnt20(+right5) ,1000+beat*65), ( sf.Pcnt20( right7),1000+beat*74), ( sf.Pcnt40(+right5),1000+beat*73), ( sf.Pcnt40( right8),1000+beat*82), ( sf.Pcnt20(+right5),1000+beat*81), ( sf.Pcnt20( right9),1000+beat*90), ( sf.Pcnt40(+right5),1000+beat*89), ( sf.Pcnt40( right10),1000+beat*98), ( sf.Pcnt20( right5) ,1000+beat*97), ( sf.Pcnt50( right11),1000+beat*106) ) ) sf.WriteFile32((+left,+right),"temp/temp.wav") (convoll,convolr)=sf.ReadFile("temp/revb2.wav") def procConvol(convol): env=sf.SimpleShape((0,0),(2048,0),(sf.Length(+convol),-40)) convolH=sf.FixSize(sf.BesselHighPass(sf.Saturate(+convol),5000,6)) convolL=sf.FixSize(sf.Multiply(env,convol)) return sf.FixSize(sf.Mix(convolH,convolL)) convoll=procConvol(convoll) convolr=procConvol(convolr) wleft =reverberate(+left,convoll) wright=reverberate(+right,convolr) left_out=sf.Normalise(sf.MixAt( (sf.Pcnt50(wleft),0), (sf.Pcnt50(left),00) )) right_out=sf.Normalise(sf.MixAt( (sf.Pcnt50(wright),0), (sf.Pcnt50(right),0) )) sf.WriteFile32((left_out,right_out),"temp/temp_postb.wav")
Ethereal Reflections
Reverberation Like Effects With Enveloped White Noise
convoll=sf.Multiply(sf.WhiteNoise(beat*4.0),sf.NumericShape((0,0),(beat*0.5,1),(beat,0.1),(beat*4,0))) convolr=sf.Multiply(sf.WhiteNoise(beat*4.0),sf.NumericShape((0,0),(beat*0.5,1),(beat,0.1),(beat*4,0))) left13 =reverberate(+left12,convoll) right13=reverberate(+right12,convolr)
rLen=20480 ns=sf.NumericShape((0,0),(rLen/2,1),(rLen,0)) convoll=sf.Multiply(+ns,sf.WhiteNoise(rLen)) convolr=sf.Multiply( ns,sf.WhiteNoise(rLen)) wleft =reverberate(left,convoll) wright=reverberate(right,convolr)
Invasion:
Audio Stretching Explaned
Sounds experienced at a different speed |
What is stretching?
Take a sound, any sound, say a song, sound concrete or just voice and stretch it out. I guess you can think of playing a 78rpm record at 33 a sort of stretch but that is not what people mean. The key idea to stretching is to uncouple pitch and time so pitch stays constant but time dilates. What took one minute might take ten.
Why might we want to stretch?
There are many reasons. I guess the most common is to convert a short sound segment into an ambient background. There are issues with this though (like repeating artefacts). Another is to create completely new effects, for example to make ultra-long impulse responses.
What Methods can be employed to perform stretches?
Well, there three ( but actually, two of them end up the same ). The most obvious is using a segmenting approach. We can chop sound up into little segments of say 100 milliseconds. If we double up each one we get a 2:1 stretch. The hope is that the 10Hz introduced by the 100milisecond segments will not be noticed. The truth is that such a naive approach makes a sound a lot like shouting through a fan. Basically, it does not work well enough for anything but Dr Who style sound effects.
The second approach is to use the Fourier Transform to separate time and pitch. The human ear is insensitive to frequencies below 32Hz other than as pressure waves (we feel pressure on our ear drums but not actual pitch). So we can take a piece of music and window an FT across it. This is a bit like the segments, we take a lot of little pieces of the sound and transform them into just pitch and phase Information. Then we can 'randomise the phase'. This means that the variation in the position of each frequency within the sample is removed and converted to something random. We can then regenerate a longer segment with the same pitch information as the original but the different phases. This gets rid of the fan effect but has other issues. It is pretty powerful though. It is this approach which Paul Stretch uses.
The third approach is again to use little segments or grains (pretty much the same thing though grains are a concept which is more applicable to granular synthesis) but convolve them with white noise. This has a mathematically similar effect to the random phase thing although it also adds more randomness to the pitch magnitudes over time. Nevertheless, guess what, convolution is usually done in frequency space, i.e. After a Fourier Transform, so actually convolution with white noise ends up pretty much the same maths as randomising phases.
People might talk about converting between sound and pictures and stuff like that. But in reality, that is just a visually appealing form of FT based stretching for people who like pretty colours.
Invasion uses a subtly different stretch approach, how does that work?
Well, it is only an evolution of two of the existing approaches. Actually, it started with Sea Of Sound, Hadean Scream was 90% there but Invasion nailed it. The key idea is to employ both convolution with white noise and granular stretching (segment based but using granular concepts). But, more than that, it uses a dispersion approach to the granular stretch. I think it is the dispersion which makes it powerful and interesting.
What I mean by dispersion is best demonstrated by listening to 'Cold'. Here I take grains of the sound and duplicate them, making hundreds of copies of the grain. Then I mix them back together but at randomised times. In Cold they follow the original sound, the grains are delayed and randomised. As there are so many of them they form a cloud of sound which swells and fills in the gaps around it. By pitch shifting the grains ( simple resampling ) I got the effect of a huge number of instruments followng on from the lead at different pitches.
It occurred to me that if I were to space out the grains and get rid of the originals, then the random,grains would rise and swell to form a new, stretched sound. Hadean screen does exactly this. The approach gets rid of one issue with Paul Stretch which really frustrates me. The issue is that some low frequency artefacts end up repeated in the output at a regular pace producing annoying effects. The attack of a piano key or the vibrato of a singer can make a very annoying repeating pattern in the output of a phase randomised stretch. The time dispersed granular approach breaks up these patterns.
In Hadean Scream I used normal impulse response reverberation to smooth out the final product; that works nicely, but is not all that ambient. If you listen to some of Eno's ambient work you can quickly tell that a key idea is soft attack. Sounds slowly appear out of he background. How to create very slow, soft attacks? Normal impulse response reverberation is not going to do it because the pulse has a sharp attack which brings out the attacks in the processed sound.
My idea (which panned out) was to make diamond shape 'super grains' of white noise. In Invasion these are 20 seconds long. They linearly grown from zero to a peak magnitude at 10 seconds and the linearly die away to nothing at 20. Using these as the impulse response for the reverberator performs that 'convolution with white noise' stretch approach but with the super soft attack and decay.
Can this approach be taken further?
Well, yes. Indead, even in Invasion and Hadean Scream I used pitch shifting as well as stretch. This means we can produce harmonised ambience from stretched sound. However, so far the stretch amount and pitch shift amounts are all fixed. I would like to make them dynamic; eventually I would like them to change in response to the sound being stretched to produce a more organic, living sound.
Can other people try out your ideas?
Yes, naturally, Sonic Field is open source. Just contact me and I will be glad to help.