def geometric_delay(sig, dur, copies, pamp=.5): """ Delay effect by copying data (with Streamix). Parameters ---------- sig: Input signal (an iterable). dur: Duration, in samples. copies: Number of times the signal will be replayed in the given duration. The signal is played copies + 1 times. pamp: The relative remaining amplitude fraction for the next played Stream, based on the idea that total amplitude should sum to 1. Defaults to 0.5. """ out = Streamix() sig = thub(sig, copies + 1) out.add(0, sig * pamp) # Original remain = 1 - pamp for unused in xrange(copies): gain = remain * pamp out.add(dur / copies, sig * gain) remain -= gain return out
def geometric_delay(sig, dur, copies, pamp=0.5): """ Delay effect by copying data (with Streamix). Parameters ---------- sig: Input signal (an iterable). dur: Duration, in samples. copies: Number of times the signal will be replayed in the given duration. The signal is played copies + 1 times. pamp: The relative remaining amplitude fraction for the next played Stream, based on the idea that total amplitude should sum to 1. Defaults to 0.5. """ out = Streamix() sig = thub(sig, copies + 1) out.add(0, sig * pamp) # Original remain = 1 - pamp for unused in xrange(copies): gain = remain * pamp out.add(dur / copies, sig * gain) remain -= gain return out
gain_low = ControlStream(0) gain_high = ControlStream(0) low = filt_low(white_noise()) high = filt_high(white_noise()) low /= 2 * max(low.take(2000)) high /= 2 * max(high.take(2000)) api = sys.argv[1] if sys.argv[1:] else None # Choose API via command-line chunks.size = 1 if api == "jack" else 16 with AudioIO(api=api) as player: player.play(low * gain_low + high * gain_high) gain_low.value = 1 while True: gain_high.value = 0 sleep(1) for unused in xrange(5): # Keeps low playing sleep(0.1) gain_high.value = 0 sleep(0.4) gain_high.value = 1 gain_low.value = 0 sleep(1) for unused in xrange(5): # Keeps high playing sleep(0.1) gain_low.value = 0 sleep(0.4) gain_low.value = 1
title = "ISO226 equal loudness curves" freqs = list(exp(line(2048, ln(20), ln(12500), finish=True))) pylab.figure(title, figsize=[8, 4.5], dpi=120) # Plots threshold freq2dB_threshold = phon2dB.iso226(None) # Threshold pylab.plot(freqs, freq2dB_threshold(freqs), color="blue", linestyle="--") pylab.text(300, 5, "Hearing threshold", fontsize=8, horizontalalignment="right") # Plots 20 to 80 phons for loudness in xrange(20, 81, 10): # in phons freq2dB = phon2dB.iso226(loudness) pylab.plot(freqs, freq2dB(freqs), color="black") pylab.text(850, loudness + 2, "%d phon" % loudness, fontsize=8, horizontalalignment="center") # Plots 90 phons freq2dB_90phon = phon2dB.iso226(90) freqs4k1 = list(exp(line(2048, ln(20), ln(4100), finish=True))) pylab.plot(freqs4k1, freq2dB_90phon(freqs4k1), color="black") pylab.text(850, 92, "90 phon", fontsize=8, horizontalalignment="center") # Plots 10 and 100 phons
out.add(dur / copies, sig * gain) remain -= gain return out # # Audio mixture # tracks = 3 # besides unpitched track dur_note = 120 * ms dur_perc = 100 * ms smix = Streamix() # Pitched tracks based on a 1:2 triangular wave table = TableLookup(line(100, -1, 1).append(line(200, 1, -1)).take(inf)) for track in xrange(tracks): env = adsr(dur_note, a=20 * ms, d=10 * ms, s=.8, r=30 * ms) / 1.7 / tracks smix.add(0, geometric_delay(new_note_track(env, table), 80 * ms, 2)) # Unpitched tracks pfuncs = [unpitched_low] * 4 + [unpitched_high] snd = chain.from_iterable( choice(pfuncs)(dur_perc, randint(0, 1)) for unused in zeros()) smix.add(0, geometric_delay(snd * (1 - 1 / 1.7), 20 * ms, 1)) # # Finishes (save in a wave file) # data = lowpass(5000 * Hz)(smix).limit(180 * s) fname = "audiolazy_save_and_memoize_synth.wav" save_to_16bit_wave_file(fname, data, rate)
from audiolazy import exp, line, ln, phon2dB, xrange import pylab title = "ISO226 equal loudness curves" freqs = list(exp(line(2048, ln(20), ln(12500), finish=True))) pylab.figure(title, figsize=[8, 4.5], dpi=120) # Plots threshold freq2dB_threshold = phon2dB.iso226(None) # Threshold pylab.plot(freqs, freq2dB_threshold(freqs), color="blue", linestyle="--") pylab.text(300, 5, "Hearing threshold", fontsize=8, horizontalalignment="right") # Plots 20 to 80 phons for loudness in xrange(20, 81, 10): # in phons freq2dB = phon2dB.iso226(loudness) pylab.plot(freqs, freq2dB(freqs), color="black") pylab.text(850, loudness + 2, "%d phon" % loudness, fontsize=8, horizontalalignment="center") # Plots 90 phons freq2dB_90phon = phon2dB.iso226(90) freqs4k1 = list(exp(line(2048, ln(20), ln(4100), finish=True))) pylab.plot(freqs4k1, freq2dB_90phon(freqs4k1), color="black") pylab.text(850, 92, "90 phon", fontsize=8, horizontalalignment="center") # Plots 10 and 100 phons freq2dB_10phon = phon2dB.iso226(10) freq2dB_100phon = phon2dB.iso226(100) freqs1k = list(exp(line(1024, ln(20), ln(1000), finish=True)))
out.add(dur / copies, sig * gain) remain -= gain return out # # Audio mixture # tracks = 3 # besides unpitched track dur_note = 120 * ms dur_perc = 100 * ms smix = Streamix() # Pitched tracks based on a 1:2 triangular wave table = TableLookup(line(100, -1, 1).append(line(200, 1, -1)).take(inf)) for track in xrange(tracks): env = adsr(dur_note, a=20 * ms, d=10 * ms, s=0.8, r=30 * ms) / 1.7 / tracks smix.add(0, geometric_delay(new_note_track(env, table), 80 * ms, 2)) # Unpitched tracks pfuncs = [unpitched_low] * 4 + [unpitched_high] snd = chain.from_iterable(choice(pfuncs)(dur_perc, randint(0, 1)) for unused in zeros()) smix.add(0, geometric_delay(snd * (1 - 1 / 1.7), 20 * ms, 1)) # # Finishes (save in a wave file) # data = lowpass(5000 * Hz)(smix).limit(180 * s) fname = "audiolazy_save_and_memoize_synth.wav" save_to_16bit_wave_file(fname, data, rate)
gain_low = ControlStream(0) gain_high = ControlStream(0) low = filt_low(white_noise()) high = filt_high(white_noise()) low /= 2 * max(low.take(2000)) high /= 2 * max(high.take(2000)) api = sys.argv[1] if sys.argv[1:] else None # Choose API via command-line chunks.size = 1 if api == "jack" else 16 with AudioIO(api=api) as player: player.play(low * gain_low + high * gain_high) gain_low.value = 1 while True: gain_high.value = 0 sleep(1) for unused in xrange(5): # Keeps low playing sleep(.1) gain_high.value = 0 sleep(.4) gain_high.value = 1 gain_low.value = 0 sleep(1) for unused in xrange(5): # Keeps high playing sleep(.1) gain_low.value = 0 sleep(.4) gain_low.value = 1
width = 79 # monospaced characters beat = 60 # bpm notes_per_beat = 4 starting_beats = 4 shuffle_fingers = True shuffle_per_string = False # Ignored when shuffle_fingers is False invert_when_backwards = True # Create notes as pairs (string_index, fret) guitar = Guitar(tuning) if shuffle_fingers and not shuffle_per_string: shuffle(fingers) num_strings = len(guitar) notes = [] inv_fingers = fingers[::-1] for forefinger_fret in xrange(first_fret, last_fret + 1): inverter = slice(None, None, (-1) ** forefinger_fret) # Alternates asc/desc if invert_when_backwards: finger_order = inv_fingers[inverter] else: finger_order = fingers for idx in orange(num_strings)[inverter]: frets = [x + forefinger_fret for x in finger_order] if shuffle_fingers and shuffle_per_string: shuffle(frets) notes.extend((idx, fret) for fret in frets) # # Tablature display #
width = 79 # monospaced characters beat = 60 # bpm notes_per_beat = 4 starting_beats = 4 shuffle_fingers = True shuffle_per_string = False # Ignored when shuffle_fingers is False invert_when_backwards = True # Create notes as pairs (string_index, fret) guitar = Guitar(tuning) if shuffle_fingers and not shuffle_per_string: shuffle(fingers) num_strings = len(guitar) notes = [] inv_fingers = fingers[::-1] for forefinger_fret in xrange(first_fret, last_fret + 1): inverter = slice(None, None, (-1)**forefinger_fret) # Alternates asc/desc if invert_when_backwards: finger_order = inv_fingers[inverter] else: finger_order = fingers for idx in orange(num_strings)[inverter]: frets = [x + forefinger_fret for x in finger_order] if shuffle_fingers and shuffle_per_string: shuffle(frets) notes.extend((idx, fret) for fret in frets) # # Tablature display #