def harpsichord_filter(power, resonance, sig, freq): with SFMemoryZone(): length = sf.Length(sig) ring = sf.SineWave(length, 50.0 + freq / 50.0) ring = sf.Multiply(sf.LinearShape((0, 0.05), (length, 0)), ring) ring = sf.DirectMix(1.0, ring) sig = sf.Multiply(sig, ring).keep() with SFMemoryZone(): end = length - 10 if end < 50: end = 50 tot = 10000.0 # 10 Seconds env = sf.LinearShape((0, 18000), (length - 25, freq * 3.0), (length, freq * 6.0)) res = sf.LinearShape((1, 0.2 * resonance), (length - 25, 0.5 * resonance), (length, 0.8 * resonance)) sig = sf.ShapedLadderLowPass(sig, env, res) env = sf.ExponentialShape((0, 10), (5, -10), (10000, -80)) env = sf.Cut(0, length, env) env = sf.Multiply( env, sf.LinearShape((0, 1), (length - 25, 1), (length, 0))) out = sf.FixSize(sf.Multiply(env, sig)) click = sf.RBJLowPass( sf.ExponentialShape((0, -10), (10, -90), (length, -100)), 5000, 1) out = sf.Mix(click, out) out = sf.Power(out, power) return sf.FixSize(out).keep()
def granular_reverberate(signal, ratio, delay, density, length=50, stretch=1, vol=1, rand=1.0, spread=1.0): with SFMemoryZone(): c_log("Granular reverb: ratio:", ratio, " delay:", delay, " density", density, " length:", length, " stretch:", stretch, " volume:", vol, "rand:", rand, "spread", spread) out = [] for grain in sf.Granulate(signal, length, 10): with SFMemoryZone(): (signal_i, at) = grain signal_i = sf.Realise(signal_i) signal_i = sf.Realise( sf.DirectRelength( signal_i, ratio - 0.01 * spread + (0.02 * spread * random.random()))) signal_i.keep() for x in range(0, density): time = delay * ( (random.random() + random.random()) * rand + (1.0 - rand)) time = abs(time) out.append((signal_i, int((at + time) * stretch))) out = mix(out) out = sf.LinearVolume(out, vol) return out.keep()
def doWind(length, hfq, vol, reverse=False): key = (length, _logRoundUp(hfq), vol, reverse) if key in _resonanceCache: if random.random() < _CACHE_PROBABILITY: return _repitch(key[1], hfq, readSwappedCache(_resonanceCache[key])) with SFMemoryZone(): # Put in a little extra and then trim it off reliably. upRatio = key[1] * 1.01 / float(hfq) out = _distant_wind(length * upRatio, hfq, qCorrect, limit, seed) out = sf.Power(out, power) if saturate: os = sf.Saturate(sf.LinearVolume(sf.FixSize(+out), 2.0)) out = sf.Mix(sf.LinearVolume(out, 1.0 - saturate), sf.LinearVolume(os, saturate)) out = sf.Realise(out) out = sf.LinearVolume(sf.FixSize(out), vol) if reverse: out = sf.Reverse(out) ret = compress(out) if _PERFORM_CACHE: # Store no more than the length we need which we work out as the # inverse scale of that used to make the signal. This should # always give enough signal so out of bounds does not happen. toCache = _repitch(hfq, key[1], ret, sf.Length(ret) / upRatio) # FIXME: Figure out how to make this long enough. # See call to _distant_wind above. _resonanceCache[key] = writeSawppedCache(toCache) return toCache.keep() else: return ret.keep() return ret
def tuned_wind(length, freq): with SFMemoryZone(): sigs = [] for i in range(1, 3): sig = byquad_filter( 'peak', byquad_filter( 'peak', sf.Mix(clean_noise(length, freq), sf.Pcnt10(sf.SineWave(length, freq))), 1.0, 64), freq, 0.1, 64) sig = byquad_filter('peak', sig, freq, 1.0, 128) sig = sf.FixSize(excite(sig, 1.0, 2.0)) sig = sf.FixSize(sf.Saturate(sf.LinearVolume(sig, 2.0))) sig = create_vibrato(sig, length, longer_than=0.5, rate=2.5, at=0.45, depth=0.5, pitch_depth=0.02) sigs.append(sig) sig = mix(sigs) return sf.FixSize(polish(sig, freq)).keep()
def violin_filter(sig, freq): with SFMemoryZone(): length = sf.Length(sig) sigs = [] bodies = violinIRs for body in bodies: sigs.append(convolve(+sig, +body)) sig = sf.Mix(sf.FixSize(sf.Clean(sf.Mix(sigs))), sig) vibAbove = 250 if length > vibAbove: # TODO feels a bit crushed - more stages? vibStart = length * 0.5 if length > 600 else vibAbove * 0.75 vibMiddle = length * 0.75 if length > 600 else vibAbove vibAmount = 0.5 if length > 1000 else 0.25 trueLen = sf.Length(+sig) l = trueLen env = sf.LinearShape((0, 0), (vibStart, 0), (vibMiddle, 1), (length, 0.75), (l, 0)) env = sf.LinearVolume(env, vibAmount) trem = sf.SineWave(l, 2.0 + random.random()) trem = sf.Multiply(env, trem) vib = +trem trem = sf.DirectMix(1, sf.Pcnt50(trem)) sig = sf.Multiply(trem, sig) vib = sf.DirectMix(1, sf.LinearVolume(vib, 0.01)) sig = sf.Resample(vib, sig) return sf.FixSize(sf.Clean(sig)).keep()
def tremulus_diapason_filter(sig, freq): with SFMemoryZone(): length = sf.Length(sig) rate = 3.0 # Clip off extreme spectra leakage (which in can have big negative compenents). env = sf.LinearShape((0, 0), (5, 1), (length - 5, 1), (length, 0)) sig = sf.Multiply(env, sig) # Filter gentally to keep the singal stable sig = sf.RBJLimitedPeaking(sig, freq * 2, 0.5, 1.0) sig = sf.RBJLowPass(sig, freq * 3, 1.0) br = freq * 9 if br > 5000.0: br = 5000.0 sig = sf.RBJLowPass(sig, br, 1.0) sig = sf.FixSize(sig) shape = sf.SineWave(length, rate) shape = sf.LinearVolume(shape, 0.5) shape = sf.DirectMix(1.0, shape) filt = byquad_filter('high', +sig, freq * 4) filt = sf.Multiply(filt, +shape) sig = sf.Mix(sig, filt) mag = 0.01 ev = sf.LinearVolume(shape, mag) ev = sf.DirectMix(1.0, ev) sig = sf.FrequencyModulate(sig, ev) return sf.FixSize(sig).keep()
def oboe_harpsichord_filter(sig, frequency, vibAbove=200): powr = 1.0 if frequency < 250: powr -= (250.0 - frequency) / 750.0 if powr < 0.5: powr = 0.5 with SFMemoryZone(): sig = soft_harpsichord_filter(power=powr, resonance=1.0, sig=sig, freq=frequency) length = sf.Length(sig) if length > vibAbove: # TODO feels a bit crushed - more stages? vibStart = length * 0.5 if length > 600 else vibAbove * 0.75 vibMiddle = length * 0.75 if length > 600 else vibAbove vibAmount = 0.5 if length > 1000 else 0.25 trueLen = sf.Length(sig) l = trueLen env = sf.LinearShape((0, 0), (vibStart, 0), (vibMiddle, 1), (l, 0)) env = sf.LinearVolume(env, vibAmount) trem = sf.SineWave(l, 2.0 + random.random()) trem = sf.MakeTriangle(trem) trem = sf.Multiply(env, trem) vib = trem trem = sf.DirectMix(1, sf.Pcnt50(trem)) sig = sf.Multiply(trem, sig) vib = sf.DirectMix(1, sf.LinearVolume(vib, 0.01)) sig = sf.Resample(vib, sig) return sig.keep()
def main(): with SFMemoryZone(): print 'Doing work' start = 10 voxl, voxr = makeBlocks(start=start, rootFrequency=64) start += 10000 tvoxl, tvoxr = makeBlocks(start=start, rootFrequency=256) voxl = sf.Mix(voxl, tvoxl) voxr = sf.Mix(voxr, tvoxr) start += 10000 tvoxl, tvoxr = makeBlocks(start=start, rootFrequency=640) voxl = sf.Mix(voxl, tvoxl) voxr = sf.Mix(voxr, tvoxr) voxl, voxr = [sf.SwapSignal(sf.FixSize(vox)) for vox in voxl, voxr] sf.WriteSignal(voxl, "temp/bells_left_b") sf.WriteSignal(voxr, "temp/bells_right_b") t = 0 l = max(sf.Length(voxl), sf.Length(voxr)) c = 0 while t < l: e = t + 2400000.0 e = min(l, e) # TODO is left and right are different lengths # will this fail? leftX = sf.Cut(t, e, voxl) rightX = sf.Cut(t, e, voxr) sf.WriteFile32((leftX, rightX), "temp/bells{0}_b.wav".format(c)) c += 1 t = e print 'Done work'
def inner(signal_): with SFMemoryZone(): signal = sf.Clean(signal_) sigs = [] l = sf.Length(signal) for inst in range(0, int(nChorus)): @sf_parallel def in_inner(): with SFMemoryZone(): print "Do" lfo = sf.PhasedSineWave(l, bandRand(minRate, maxRate), random.random()) lfo = sf.LinearVolume(lfo, bandRand(minDepth, maxDepth)) nsg = sf.TimeShift(signal, lfo) lfo = sf.PhasedSineWave(l, bandRand(minRate, maxRate), random.random()) lfo = sf.LinearVolume(lfo, bandRand(minVol, maxVol)) lfo = sf.DirectMix(1, lfo) nsg = sf.Multiply(lfo, nsg) print "Done" return sf.SwapSignal(sf.Finalise(nsg)) sigs.append(in_inner()) ret = sf.Finalise(sf.Mix(sigs)) return ret.keep()
def _doVib(env, signal): ''' Adds vibrato to a signal based on the passed in envelope. :param: env, the modulation envolope between 0 (no modulaltio) and 1 (full modulation). :type: env, SFSignal. :param: signal, the signal to modulate. :type: signal, SFSignal. :return: an SFSignal of the modulate version of the passed in signal. Note that the returned signal will be flushed. ''' with SFMemoryZone(): l = sf.Length(signal) trem = sf.FixSize( sf.MakeTriangle( sf.FixSize(sf.Mix(sf.SineWave(l, 4.1), sf.SineWave(l, 3.9))))) trem = sf.Multiply(+env, trem) vib = +trem trem = sf.DirectMix(1, sf.Pcnt50(trem)) signal = sf.Multiply(trem, signal) vib = sf.DirectMix(1, sf.LinearVolume(vib, 0.01)) signal = sf.Resample(vib, signal) return sf.FixSize(sf.Finalise(signal)).keep()
def declick(signal, thresh = 0.04, cutoff = 1000): print 'Declicking %10.6f, %d.' % (thresh, cutoff) with SFMemoryZone(): events = 0 signal = sf.FixSize(signal) up = signal.replicateEmpty() down = signal.replicateEmpty() old = 0.0 oldOld = 0.0 width = 192 * 1 # TODO: Convert all this into Java for speed. for pos in xrange(signal.getLength()): new = signal.getSample(pos) diff = old - new sdiff = (old - oldOld) - diff if abs(diff) > thresh or abs(sdiff) > thresh: events += 1 #print 'Click Event, diff: %10.6f sdiff: %10.6f count: %d sample: %d' % (diff, sdiff, events, pos) for x in xrange(width): v = 1.0 - (x / width) up.setSample(pos + x, v) v = v + up.getSample(pos - x) if v > 1.0: v = 1.0 up.setSample(pos - x, v) oldOld = old old = new if events == 0: print 'No Click Events' return signal.keep() up = sf.FixSize(sf.Mix( sf.RBJLowPass(up, 100, 1.0), sf.Reverse(sf.RBJLowPass(sf.Reverse(up), 100, 1.0)) )).realise() minV = 0.0 for pos in xrange(signal.getLength()): v = up.getSample(pos) if v < minV: minV = v for pos in xrange(signal.getLength()): v = up.getSample(pos) up.setSample(pos, v - minV) up = sf.FixSize(up) for pos in xrange(signal.getLength()): down.setSample(pos, 1.0 - up.getSample(pos)) filt = sf.RBJLowPass(signal, cutoff, 1.0) filt = sf.Multiply(filt, up) nFlt = sf.Multiply(signal, down) print 'Declicked %i events.' % events return sf.FixSize(sf.Mix(filt, nFlt)).keep()
def harpsiPipe(midi_in, beat, temperament, velocity, pan): with SFMemoryZone(): a = distant_flute_pipe(midi_in, beat, temperament, velocity, pan) b = sloped_golberg_harpsichord(midi_in, beat, temperament, velocity, pan) a = a.get() b = b.get() return (sf.FixSize(sf.Mix(sf.Pcnt60(a[0]), sf.Pcnt40(b[0]))).keep(), sf.FixSize(sf.Mix(sf.Pcnt60(a[1]), sf.Pcnt40(b[1]))).keep())
def femail_soprano_a_filter(vox, freq): with SFMemoryZone(): length = sf.Length(vox) vox = _vox_filter(vox, freq, 860, 2050, 2850) a = sf.BesselLowPass(+vox, freq, 2) b = sf.Power(sf.BesselHighPass(vox, freq * 4.0, 2), 1.35) b = sf.Clean(b) b = sf.ButterworthHighPass(b, freq * 1.5, 6) a = sf.ButterworthHighPass(a, freq * 0.75, 6) return mix(sf.Pcnt75(a), sf.Pcnt25(b)).keep()
def femail_soprano_ah_filter(vox, freq): with SFMemoryZone(): length = sf.Length(vox) print length, freq vox = _vox_filter(vox, freq, 850, 1200, 2800) lower = sf.BesselLowPass(+vox, freq, 2) higher = sf.Power(sf.BesselHighPass(vox, freq * 4.0, 2), 1.25) higher = sf.Clean(higher) higher = sf.ButterworthHighPass(higher, freq * 1.5, 6) lower = sf.ButterworthHighPass(lower, freq * 0.75, 6) return sf.Realise(mix(sf.Pcnt95(lower), sf.Pcnt5(higher))).keep()
def _distant_wind(length, freq, qCorrect=1.25, limit=False, seed=-60): with SFMemoryZone(): length += 250.0 base = sf.Mix(clean_noise(length, freq * 4.0), sf.ExponentialVolume(sf.SineWave(length, freq), seed)) env = [] # Super imposted last two postions does not matter. v = 0.5 t = 0 while t < length: if random.random() > 0.5: v *= 1.1 if v > 1.0: v = 0.9 else: v *= 0.9 env += [(t, v)] # Constrained random walk envelope in 100 ms steps. t += 100 #base = sf.Multiply(sf.LinearShape(env), base) out = [] xq = 1.8 if freq > 640 else 2.0 if freq > 256 else 2.5 if freq > 128 else 3.0 xq *= qCorrect with SFMemoryZone(): for q in (16, 32, 48): out += [ byquad_filter('peak' if not limit else 'limited peak', base, freq, 0.5, q * xq) ] out = sf.Mix(out) out = sf.ButterworthLowPass(out, freq * 1.25, 4) out = sf.ButterworthLowPass(out, freq * 1.25, 4).keep() st = sf.Cut(0, length / 2.0, out) ed = sf.Cut(length / 2.0, length, out) st = sf.Magnitude(st) ed = sf.Magnitude(ed) rt = st / ed if ed != 0 else 0 ev = sf.LinearShape((0.0, 1.0), (length, rt)).realise() out = sf.Multiply(ev, out) return sf.FixSize(sf.Cut(250, length, out)).keep()
def femail_soprano_ma_filter(vox, freq): with SFMemoryZone(): length = sf.Length(vox) vox = vox_humana_femail_soprano_a(vox, length, freq) if length > 128: qsh = sf.LinearShape((0, 0.1), (120, 2), (length, 0.1)) msh = sf.LinearShape((0, 1.0), (120, 1.0), (length, 0.0)) mshr = sf.LinearShape((0, 0.0), (120, 0.0), (length, 1.0)) init = byquad_filter('low', +vox, freq, qsh) vox = sf.Multiply(vox, mshr) init = sf.Multiply(init, msh) vox = mix(vox, init) vox = sf.FixSize(polish(vox, freq)) return vox.keep()
def synthichord_filter(sig, freq): with SFMemoryZone(): length = sf.Length(sig) vibAbove = 250 if length > vibAbove: # TODO feels a bit crushed - more stages? vibStart = length * 0.5 if length > 600 else vibAbove * 0.75 vibMiddle = length * 0.75 if length > 600 else vibAbove vibAmount = 0.5 if length > 1000 else 0.25 trueLen = sf.Length(+sig) l = trueLen env = sf.LinearShape((0, 0), (vibStart, 0), (vibMiddle, 1), (length, 0.75), (l, 0)) env = sf.LinearVolume(env, vibAmount) trem = sf.SineWave(l, 2.0 + random.random()) trem = sf.MakeTriangle(trem) trem = sf.Multiply(env, trem) vib = +trem trem = sf.DirectMix(1, sf.Pcnt50(trem)) sig = sf.Multiply(trem, sig) vib = sf.DirectMix(1, sf.LinearVolume(vib, 0.01)) sig = sf.Resample(vib, sig) env = sf.ExponentialShape((0, sf.ToDBs(18000)), (length, sf.ToDBs(freq * 2.5))) env = sf.Cut(0, length, env) env = sf.Multiply( env, sf.LinearShape((0, 1), (length - 35, 1), (length, 0.1))) res = None if length > 50: res = sf.LinearShape((0, 0.5), (length - 50, 0.5), (length, 0.9)) else: res = sf.LinearShape((0, 0.5), (length, 0.8)) res = sf.Cut(0, length, res) sig, env, res = sf.MatchLengths((sig, env, res)) out = sf.ShapedLadderLowPass(sig, env, res) attack = 5 env = None if length > 50: env = sf.ExponentialShape((0, -40), (attack, 0), (length, -20)) env = sf.Multiply( env, sf.LinearShape((0, 1), (length - 20, 1), (length, 0))) else: env = sf.LinearShape((0, 0.00), (attack, 0), (length, 0)) out = sf.Multiply(env, out) return sf.FixSize(polish(out, freq)).keep()
def in_inner(): with SFMemoryZone(): print "Do" lfo = sf.PhasedSineWave(l, bandRand(minRate, maxRate), random.random()) lfo = sf.LinearVolume(lfo, bandRand(minDepth, maxDepth)) nsg = sf.TimeShift(signal, lfo) lfo = sf.PhasedSineWave(l, bandRand(minRate, maxRate), random.random()) lfo = sf.LinearVolume(lfo, bandRand(minVol, maxVol)) lfo = sf.DirectMix(1, lfo) nsg = sf.Multiply(lfo, nsg) print "Done" return sf.SwapSignal(sf.Finalise(nsg))
def spatialise(osg): with SFMemoryZone(): print 'Do spatialise' osi = sf.Invert(osg) dhz = 0.5 dly = 250.0 md1 = sf.PhasedSineWave(sf.Length(osg), 0.01, 0.0) md1 = sf.LinearVolume(md1, 100) os1 = sf.AnalogueChorus(osg, dly, md1, 1.25, 0.7, 18000.0) md1 = sf.PhasedSineWave(sf.Length(osg), 0.01, 0.5) md1 = sf.LinearVolume(md1, 100) os2 = sf.AnalogueChorus(osg, dly, md1, 1.25, 0.7, 18000.0) oso = [sf.Mix([os1[0], os2[0]]), sf.Mix([os1[1], os2[1]])] oso = [sf.FixSize(sf.Mix(sf.FixSize(s), osi)).keep() for s in oso] print 'Done spatialise' return oso
def oboe_filter(sig, freq): with SFMemoryZone(): length = sf.Length(sig) # Clip off extreme spectra leakage (which in can have big negative compenents). env = sf.LinearShape((0, 0), (5, 1), (length - 5, 1), (length, 0)) sig = sf.Multiply(env, sig) sig = sf.RBJPeaking(sig, freq * 3, 0.2, 5) sig = sf.RBJPeaking(sig, freq * 5, 0.5, 4) sig = sf.RBJPeaking(sig, freq * 7, 1, 4) sig = sf.RBJNotch(sig, freq * 2, 1.0, 1.0) sig = sf.Mix(+sig, sf.RBJNotch(sig, freq, 1.0, 1.0)) sig = sf.RBJLowPass(sig, freq * 9, 1.0) br = freq * 9 if br > 5000.0: br = 5000.0 sig = sf.RBJLowPass(sig, br, 1.0) return sf.FixSize(sf.Clean(sig)).keep()
def makeBlocks(length=3600000, start=10, rootFrequency=256): with SFMemoryZone(): # Ten times this is the hassDelay left and right. haasWalkLeft = BrownianWalk(maxDenominator=3, maxNumerator=10) haasWalkRight = BrownianWalk(maxDenominator=3, maxNumerator=10) # Balance walk which also gives the volume. balWalkLeft = BrownianWalk() balWalkRight = BrownianWalk() # Length walk. lenWalk = BrownianWalk(maxDenominator=4, maxNumerator=4) # Frequency walker. fSpread = 8 if rootFrequency > 1023 else 4 if rootFrequency > 255 else 3 freqWalk = BrownianWalk(maxDenominator=fSpread, maxNumerator=fSpread) at = start sigsLeft = [] sigsRight = [] while at < length: atLeft = at + haasWalkLeft.next() * 10 atRight = at + haasWalkRight.next() * 10 thisLen = lenWalk.next() * 10000 brightness = random() * 2 + 1.0 hit = random() * 2 + 1.0 isBowl = random() > 0.5 isBowl = False frequency = freqWalk.next() * rootFrequency print "%6g, %6g, %6g, %6g, %6g, %3g, %s," % ( frequency, atLeft, atRight, thisLen, brightness, hit, str(isBowl)) sig = primeBell(frequency=frequency, brightness=1.0, length=thisLen, hit=1.0, isBowl=isBowl) sigsLeft += [(sig, atLeft)] sigsRight += [(sig, atRight)] at += thisLen * 1.25 print sigsLeft, sigsRight return [ sf.SwapSignal(sf.FixSize(sf.MixAt(sigs))) for sigs in sigsLeft, sigsRight ]
def reverberate_inner(signal, convol, grain_length): with SFMemoryZone(): mag = sf.Magnitude(signal) if mag > 0: signal_ = sf.Concatenate(signal, sf.Silence(grain_length)) len = sf.Length(signal_) signal_ = FREQ_DOMAIN(signal_) signal_ = sf.CrossMultiply(convol, signal_) signal_ = TIME_DOMAIN(signal_) newMag = sf.Magnitude(signal_) # HACK! TODO: if not newMag: return signal signal_ = sf.LinearVolume(signal_, mag / newMag) # tail out clicks due to amplitude at end of signal return sf.Clean(sf.Cut(0, len, signal_)).keep() else: return signal.keep()
def tremulus_flute_filter(sig, freq): with SFMemoryZone(): length = sf.Length(sig) rate = 3.0 # Clip off extreme spectra leakage (which in can have big negative compenents). env = sf.LinearShape((0, 0), (5, 1), (length - 5, 1), (length, 0)) sig = sf.Multiply(env, sig) shape = sf.SineWave(length, rate) shape = sf.LinearVolume(shape, 0.5) shape = sf.DirectMix(1.0, shape) filt = byquad_filter('high', +sig, freq * 2) filt = sf.Multiply(filt, +shape) sig = sf.Mix(sig, filt) mag = 0.01 ev = sf.LinearVolume(shape, mag) ev = sf.DirectMix(1.0, ev) sigf = sf.FrequencyModulate(+sig, ev) return sf.FixSize(sf.Mix(sig, sigf)).keep()
def _goldberg_filter(sig, frequency, bright): global goldbergSlope with SFMemoryZone(): sig = oboe_harpsichord_filter(sig, frequency, 75) length = sf.Length(sig) wetV = sf.ValueAt(goldbergSlope, frequency) dryV = 1.0 - wetV wet = sf.FixSize(sf.Saturate(sf.LinearVolume(sig, 2.0))) wet = sf.LinearVolume(wet, wetV) dry = sf.LinearVolume(sig, dryV) slope = (250.0 - frequency) / 250.0 vol = 1.0 if slope < 0.0 else slope + 1.0 sig = sf.Mix(wet, dry) if bright and length > 20.0: sig = sf.RBJPeaking(sig, frequency * 4, 1.0, 1) reclip = sf.LinearShape((0, 1), (length - 10, 1), (length, 0)) sig = sf.Multiply(reclip, sig) sig = sf.FixSize(sig) return sf.LinearVolume(sig, vol).keep()
def doWork(left, right, doChorus=False, doSpatial=True): print 'Do work' if doSpatial: with SFMemoryZone(): left1, right1 = spatialise(left) left2, right2 = spatialise(right) left = sf.MixAt((left1, 0), (sf.Pcnt10(left2), 50)).keep() right = sf.MixAt((right1, 0), (sf.Pcnt10(right2), 40)).keep() if doChorus: left, right = chorus(left, right, minDepth=02.0, maxDepth=10.0, minVol=0.7, maxVol=1.0, nChorus=16.0) print 'Done work' return left, right
def sing( hint, pitch, lengthIn, v, vl, vr, voice, velocity_correct_, quick_factor, sub_bass, flat_env, pure, raw_bass, decay, bend, mellow, smooth, slope, ): if pitch > 20000: raise ValueError('Pitch too great {0}'.format(pitch)) with SFMemoryZone(): velocity_correct = velocity_correct_ length = lengthIn tp = 0 # minimum play time if length < 192: length = 192 tp = 0 elif length < 363: length += 128 tp = 1 elif length < 512: length += 256 tp = 2 elif length < 1024: length += 128 tp = 3 else: tp = 4 sig = [] if pure: x = 1 else: if pitch < 330: x = 5 elif pitch < 880: x = 6 else: x = 3 for x in range(0, x): vc = voice(length, pitch * (1.0 + random.random() * 0.005)) if quick_factor: vc = sf.Multiply( linearEnv(vc, [(0, 0), (24, 1), (sf.Length(vc) - 24, 1), (sf.Length(vc), 0)]), vc) sig.append( sf.LinearVolume( sf.Concatenate(sf.Silence(24 * random.random()), vc), random.random() + 0.25)) else: sig.append(sf.LinearVolume(vc, random.random() + 0.25)) sig = sf.FixSize(sf.Mix(sig)) length = sf.Length(sig) if decay: # -60 db at 1 minute dbs = -60.0 * float(length) / float(decay) env = sf.ExponentialShape((0, 0), (length, dbs)) sig = sf.Multiply(sig, env) pHint = hint[0] nHint = hint[1] shine = False env = None if quick_factor: if tp == 0: if pHint == "T": q = 32 else: q = 64 if nHint == "T": p = 32 else: p = 64 q *= quick_factor env = linearEnv(sig, [(0, 0), (q, 1), (192 - p, 0.5), (length, 0)]) if hint == "TT": velocity_correct *= 0.8 elif hint == "NN" and pitch > 660: shine = True velocity_correct *= 0.5 elif tp == 1 or flat_env: if pHint == "T": q = 48 else: q = 96 if nHint == "T": p = 64 else: p = 128 q *= quick_factor env = linearEnv(sig, [(0, 0), (q, 0.75), (length - p, 1.0), (length, 0)]) if hint == "TT": velocity_correct *= 0.8 if hint == "TT": velocity_correct *= 0.8 elif hint == "NN" and pitch > 880: shine = True velocity_correct *= 0.6 elif tp == 2: env = linearEnv(sig, [(0, 0), (96 * quick_factor, 0.75), (length - 256, 1.0), (length, 0)]) elif tp == 3: if length < 1280: env = linearEnv(sig, [(0, 0), (64 * quick_factor, 0.5), (256, 1), (512, 0.75), ((length - 512) / 2.0 + 512, 0.5), (length, 0)]) else: env = linearEnv(sig, [(0, 0), (64 * quick_factor, 0.5), (256, 1), (512, 0.75), (length - 512, 0.75), (length, 0)]) else: env = linearEnv(sig, [(0, 0), (64 * quick_factor, 0.25), (512, 1), (length / 2, 0.75), (length, 0)]) if bend: mod = sf.LinearShape((0, 0.995), (length, 1.005)) if env: mod = sf.Mix(mod, sf.LinearVolume(+env, 0.01)) # if we have envelope extension then we don't do this as # it get really hard to get the lengths correct and make # sense of what we are trying to do. KISS if sf.Length(+sig) == sf.Length(+mod): sig = sf.FrequencyModulate(sig, mod) sig = sf.FixSize(sig) if mellow: if pitch < 256: if sub_bass: if pitch < 128: sig = sf.Mix( granular_reverberate(+sig, ratio=0.501, delay=256, density=32, length=256, stretch=1, vol=0.20), granular_reverberate(+sig, ratio=0.2495, delay=256, density=32, length=256, stretch=1, vol=0.10), sig) elif pitch < 192: sig = sf.Mix( granular_reverberate(+sig, ratio=0.501, delay=256, density=32, length=256, stretch=1, vol=0.25), sig) else: sig = sf.Mix( granular_reverberate(+sig, ratio=0.501, delay=256, density=32, length=256, stretch=1, vol=0.15), sig) if raw_bass: sig = sf.BesselLowPass(sig, pitch * 8.0, 1) else: 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)) if env: sig = sf.Multiply(sig, env) # Aggressively clean up an dc offset or other issue on the tail. sig = sf.RTrim(sig) length = sf.Length(sig) sig = sf.Multiply( sf.LinearShape(((0, 1), (length - 10, 1), (length, 0))), sig) sig = sf.FixSize(sig) if smooth: cnv = sf.WhiteNoise(10240) cnv = sf.ButterworthHighPass(cnv, 32, 4) if shine: q = 640 print "Shine" else: q = 256 cnv = sf.Cut(5000, 5000 + q, cnv) cnv = sf.Multiply(cnv, sf.LinearShape((0, 0), (32, 1), (q, 0))) sigr = convolve(+sig, cnv) length = sf.Length(sigr) env = None if length > 300: env = linearEnv(sigr, [(0, 0), (256, 1), (length - 20, 1.5), (length, 0)]) else: env = linearEnv(sigr, [(0, 0), (length / 2.0, 1), (length, 0)]) sigr = sf.Multiply(env, sigr) sig = sf.Mix(sf.Pcnt20(sigr), sf.Pcnt80(sig)) slopeEnv = sf.ExponentialShape(slope) velocity_correct *= sf.ValueAt(slopeEnv, pitch) print 'VCorrect: {0}'.format(velocity_correct) note = sf.LinearVolume(sf.FixSize(sig), v) notel = sf.LinearVolume(note, vl * velocity_correct).keep() noter = sf.LinearVolume(note, vr * velocity_correct).keep() return notel, noter
def soft_harpsichord_filter(power, resonance, sig, freq, attack=2, triangle=True): length = sf.Length(sig) if attack > 20: raise ValueError('Attack too large; must be <= 20.') with SFMemoryZone(): ring = sf.SineWave(length, 65 * random.random() * 10) if triangle: ring = sf.MakeTriangle(ring) quant = 0.1 if freq < 256: quant = 0.3 elif freq < 512: quant = 0.2 ring = sf.Multiply(sf.LinearShape((0, quant), (length, 0)), ring) ring = sf.DirectMix(1.0, ring) sig = sf.Multiply(sig, ring).keep() with SFMemoryZone(): sig = sf.Reverse(sig) tot = 10000.0 # 10 Seconds max_len = 10000.0 tLen = max_len if max_len > length else length q1 = freq * 7 q2 = freq * 3 if freq > 440: q2 *= 0.75 q1 *= 0.75 if freq > 660: q2 *= 0.75 q1 *= 0.75 env = None if length > 60: env = sf.ExponentialShape((0, sf.ToDBs(18000)), (50, sf.ToDBs(q1)), (max_len, sf.ToDBs(q2)), (tLen, sf.ToDBs(q1))) else: env = sf.ExponentialShape((0, sf.ToDBs(18000)), (max_len, sf.ToDBs(q2)), (tLen, sf.ToDBs(q2))) env = sf.Cut(0, length, env) env = sf.Multiply( sf.ExponentialShape((0, 0), (length - 10, 0), (length, -20)), env) if length > 50: env = sf.Multiply( env, sf.LinearShape((0, 1), (length - 35, 1), (length, 0.1))) else: env = sf.Multiply(env, sf.LinearShape((0, 1), (length, 0.1))) res = sf.LinearShape((0, 0.2 * resonance), (max_len, 0.5 * resonance), (tLen, 0.5 * resonance)) res = sf.Cut(0, length, res) env = sf.Multiply( sf.ExponentialShape((0, 0), (length - 10, 0), (length, 10)), env) sig, env, res = sf.MatchLengths((sig, env, res)) out = sf.ShapedLadderLowPass(sig, env, res) length = sf.Length(out) if power != 1.0: out = sf.FixSize(sf.Power(out, power)) env = None if length > 50: env = sf.ExponentialShape((0, -40), (attack, 0), (50, -10), (max_len, -80), (tLen, -80)) env = sf.Cut(0, length, env) env = sf.Multiply( env, sf.LinearShape((0, 0), (10, 1), (length - 25, 1), (length, 0))) else: env = sf.LinearShape((0, 0), (10, 1), (length, 0)) out = sf.Multiply(env, out) return sf.FixSize(polish(out, freq)).keep()
def convolve(signal, convolution): with SFMemoryZone(): ls = sf.Length(signal) lc = sf.Length(convolution) convol_ = FREQ_DOMAIN(sf.Concatenate(convolution, sf.Silence(ls))) return sf.Finalise(reverberate_inner(signal, convol_, lc)).keep()
def primeBell(frequency = 440 , brightness = 1.0, length = 10000, hit = 1.0, isBowl = True): with SFMemoryZone(): saturate = 0.0 qCorrect = 3.0 if frequency > 2000: # Ouch. frequency *= 0.5 saturate = 0.1 qCorrect = 1.0 qc = 1.0 if brightness < 2.0 else 3.0 harmonics = dullRange if brightness < 2.0 else brightRange harmonics = tweakRandom(harmonics(), 0.05) if isBowl: length += 4000 + length with SFMemoryZone(): gen = make_addtive_resonance( qCorrect = qCorrect, post = None, rollOff = 3.0, power = brightness, harmonics = harmonics, seed = -40, saturate = saturate ) sig = gen(length, frequency).keep() sig = sf.Mix( sig, sf.RBJLowPass( sf.Multiply( sf.WhiteNoise(30), sf.LinearShape((0, hit/4.0), (30,0)) ), frequency * 4.0, 2.0 ) ) peak = 2000 if isBowl else 1 env = sf.LinearShape( (0, frequency if isBowl else 18000), (peak, 18000 if isBowl else frequency * 4.0), (length, frequency) ) res = sf.LinearShape((1, 1.0),(length,3.0 if isBowl else 1.5)) sig = sf.ShapedRBJLowPass(sig, env, res) # A mixture of linear and exponential enveloping. env = sf.Multiply( sf.LinearShape( (0, 0), (peak, 1), (length, 0)), sf.ExponentialShape((0, 0), (peak, 0), (length, -30)) ) out = sf.FixSize(sf.Multiply(env, sig)) return out.keep()
def ma(l): with SFMemoryZone(): return sf.Finalise(sf.MixAt(l)).keep()