1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
"""
01-dynamic-range.py - Adjust the dynamic range of the signal.
Comparison of three objects used to adjust the dynamic range of the signal.
- Compress : Reduces the dynamic range of an audio signal.
- Expand : Increases the dynamic range of an audio signal.
- Gate : Allows a signal to pass only when its amplitude is above a threshold.
These three objects, by default, process independently each audio stream
relatively to its own RMS value. This can be a problem if they are passed
a stereo signal (or any multiphonic signals) where both channels should be
processed in the same way.
An alternative usage to the one illustrated below is to mix a multi-channel
signal prior to the dynamic processor and to tell the object to output the
amplitude value that should be applied to all streams at once. Something
like this:
>>> sf = SfPlayer("your/stereo.sound.wav")
>>> cmp = Compress(sf.mix(1), thresh=-18, ratio=3, outputAmp=True)
>>> # Compress both signal with the common amplitude curve.
>>> compressed = sf * cmp
"""
from pyo import *
s = Server().boot()
# The original source.
src = SfPlayer("../snds/drumloop.wav", loop=True)
# The three dynamic processing.
cmp = Compress(src, thresh=-18, ratio=3, risetime=0.005, falltime=0.05, knee=0.5)
exp = Expand(src, downthresh=-32, upthresh=-12, ratio=3, risetime=0.005, falltime=0.05)
gat = Gate(src, thresh=-40, risetime=0.005, falltime=0.05)
# These are labels that are shown as the scope window title.
labels = ["Original", "Compressed", "Expanded", "Gated"]
# List of signals to choose from.
signals = [src, cmp, exp, gat]
# Selector is used here to choose which signal to listen to.
output = Selector(signals)
# Converts the signal from mono to stereo.
stout = output.mix(2).out()
# Live oscilloscope of the alternated signals.
sc = Scope(output, wintitle="=== Original ===")
# The endOfLoop function cycles through the different signals
# and change the selection of the Selector object.
num_of_sigs = len(signals)
c = 1
def endOfLoop():
global c
output.voice = c
if sc.viewFrame is not None:
sc.viewFrame.SetTitle("=== %s ===" % labels[c])
c = (c + 1) % num_of_sigs
# endOfLoop is called every time the SfPlayer reaches the end of the sound.
tf = TrigFunc(src["trig"], endOfLoop)
s.gui(locals())
|