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
noctaves = abs(log2(max_freq/min_freq)) octave_duration = duration / noctaves smix = Streamix() data = [] # Global: keeps one parcial "track" for all uses (but the first) # Inits "data" def partial(): smix.add(octave_duration, partial_cached()) # Next track/partial event # Octave-based frequency values sequence scale = 2 ** line(duration, finish=True) partial_freq = (scale - 1) * (max_freq - min_freq) + min_freq # Envelope to "hide" the partial beginning/ending env = [k ** 2 for k in window.hamming(int(round(duration)))] # The generator, properly: for el in env * sinusoid(partial_freq) / noctaves: data.append(el) yield el # Replicator ("track" data generator) def partial_cached(): smix.add(octave_duration, partial_cached()) # Next track/partial event for el in data: yield el # Play! smix.add(0, partial()) # Starts the mixing with the first track/partial 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(True, api=api) as player: player.play(smix, rate=rate)
octave_duration = duration / noctaves smix = Streamix() data = [] # Global: keeps one parcial "track" for all uses (but the first) # Inits "data" def partial(): smix.add(octave_duration, partial_cached()) # Next track/partial event # Octave-based frequency values sequence scale = 2**line(duration, finish=True) partial_freq = (scale - 1) * (max_freq - min_freq) + min_freq # Envelope to "hide" the partial beginning/ending env = [k**2 for k in window.hamming(int(round(duration)))] # The generator, properly: for el in env * sinusoid(partial_freq) / noctaves: data.append(el) yield el # Replicator ("track" data generator) def partial_cached(): smix.add(octave_duration, partial_cached()) # Next track/partial event for el in data: yield el # Play! smix.add(0, partial()) # Starts the mixing with the first track/partial with AudioIO(True) as player: player.play(smix, rate=rate)
class Player: """ Classe Player, gerencia um player de Audio. É destruído no STOP. Ao pausar apenas para de exibir novos valores """ def __init__(self, lista_filtros, ncanais=1,rate=44100): """ Inicia o Player. lista_filtros: lista de filtros aplicados, se for uma tupla, se trata de uma preset. pos: Posição Inicial no preset """ self.filtros = lista_filtros if self.filtros is not None: self.filter = CascadeFilter(self.filtros) else: self.filter = CascadeFilter() self.ncanais = ncanais self.release = 0.05*filters.s self.rate = rate self.player = AudioIO() self.streamix = Streamix(True) self.input = ChangeableStream(self.player.record(nchannels=ncanais,rate=self.rate)) self.input.last = 0. self.stream = ChangeableStream(self.filter(self.input)) self.stream.last = 0. self.player.play(self.streamix, rate=self.rate) self.streamix.add(0,self.stream) def last_input_output(self): """ Função que retorna os últimos valores de input e output Na forma de tupla (in,out) """ try: return (self.input.last, self.stream.last) except: return (0,0) def muda_filtro(self, novos_filtros, window): """ Muda o filtro aplicado, garantindo que não haja um "click" ao fazer isso """ #self.chamando = True novo_filtro = CascadeFilter(novos_filtros) last = self.stream.last self.stream.limit(0).append(line(self.release,last,0)) self.stream = ChangeableStream(novo_filtro(self.input)) self.stream.last = last self.streamix.add(0, self.stream) def __del__(self): if not self.player.finished: self.player.close() #self.playerGrava.close() def pausar (self): """ Para o player """ if not self.player.finished: self.player.close() def tocar (self, lista_filtros=None): """ Reinicia o player (tanto quando ele é pausado como parado) """ if lista_filtros is None: lista_filtros = self.filtros self.__init__(lista_filtros,ncanais=self.ncanais,rate=self.rate)
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)
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)
dur = beat_duration / notes_per_beat # Per note smix = Streamix() # That's our sound mixture env = adsr(dur, a=40*ms, d=35*ms, s=.6, r=70*ms).take(inf) # Envelope # Effects used def distortion(sig, multiplier=18): return atan(multiplier * sig) * (2 / pi) # Intro count synth filt = (1 - z ** -2) * .5 if starting_beats > 0: inoisy_stream = filt(gauss_noise()) * env inoisy_thub = thub(inoisy_stream.append(0).limit(beat_duration), starting_beats) inoisy = chain.from_iterable(repeat(inoisy_thub).limit(starting_beats)) smix.add(.1 * s, inoisy) smix.add(starting_beats * beat_duration - dur, []) # Event timing # Wavetable lookup initialization square_table = TableLookup([1] * 256 + [-1] * 256) harmonics = dict(enumerate([1, 3, 2, 1, .3, .1, .7, .9, 1, 1, .5, .4, .2], 1)) table = sin_table.harmonize(harmonics).normalize() mem_table = (3 * saw_table + (sin_table - saw_table) ** 3).normalize() # Notes synth midi_tuning = str2midi([gs.tune for gs in guitar]) midi_pitches = [midi_tuning[string_idx] + fret for string_idx, fret in notes] for freq in midi2freq(midi_pitches): ks_memory = .1 * gauss_noise() + .9 * mem_table(freq * Hz) ks_snd = distortion(karplus_strong(freq * Hz, tau=.2 * s,
env = adsr(dur, a=40 * ms, d=35 * ms, s=.6, r=70 * ms).take(inf) # Envelope # Effects used def distortion(sig, multiplier=18): return atan(multiplier * sig) * (2 / pi) # Intro count synth filt = (1 - z**-2) * .5 if starting_beats > 0: inoisy_stream = filt(gauss_noise()) * env inoisy_thub = thub( inoisy_stream.append(0).limit(beat_duration), starting_beats) inoisy = chain.from_iterable(repeat(inoisy_thub).limit(starting_beats)) smix.add(.1 * s, inoisy) smix.add(starting_beats * beat_duration - dur, []) # Event timing # Wavetable lookup initialization square_table = TableLookup([1] * 256 + [-1] * 256) harmonics = dict(enumerate([1, 3, 2, 1, .3, .1, .7, .9, 1, 1, .5, .4, .2], 1)) table = sin_table.harmonize(harmonics).normalize() mem_table = (3 * saw_table + (sin_table - saw_table)**3).normalize() # Notes synth midi_tuning = str2midi([gs.tune for gs in guitar]) midi_pitches = [midi_tuning[string_idx] + fret for string_idx, fret in notes] for freq in midi2freq(midi_pitches): ks_memory = .1 * gauss_noise() + .9 * mem_table(freq * Hz) ks_snd = distortion(karplus_strong(freq * Hz, tau=.2 * s, memory=ks_memory))