def init_sound(self): """ Load the wavfile with :mod:`scipy.io.wavfile` , converting int to float as needed. Create a sound table, resampling sound if needed. """ fs, audio = wavfile.read(self.path) if audio.dtype in ['int16', 'int32']: audio = int_to_float(audio) # load file to sound table if self.server_type == 'pyo': self.dtable = pyo.DataTable(size=audio.shape[0], chnls=prefs.NCHANNELS, init=audio.tolist()) # get server to determine sampling rate modification and duration server_fs = self.dtable.getServer().getSamplingRate() self.duration = float(self.dtable.getSize()) / float(fs) self.table = pyo.TableRead(table=self.dtable, freq=float(fs) / server_fs, loop=False, mul=self.amplitude) elif self.server_type == 'jack': # attenuate amplitude audio = audio * self.amplitude self.duration = float(audio.shape[0]) / fs # resample to match our audio server's sampling rate if fs != self.fs: new_samples = self.duration * self.fs audio = resample(audio, new_samples) self.table = audio self.initialized = True
def __init__(self, input=None, buf_size=SAMPLE_RATE//4, overlap=0, patience=None, buffer_count=2, mul=1, add=0): """ Parameters ---------- input : PyoObject Parent PyoObject (stub) length : int Number of samples per buffer overlap : int Number of overlapping samples between adjacent buffers """ pyo.PyoObject.__init__(self, mul, add) self.input = input self.buf_size = buf_size self.overlap = overlap self.patience = patience self.fifo = Queue() self.is_tfilling = True # filling tables (upon initial play) self.is_qfilling = False # filling queue (until patience reached) self.is_ready = False # ready to play self.is_playing = False # should be playing when ready # Tables and table readers do process grains of audio self.curr_buf = 0 assert overlap <= buf_size / 2 self.buffer_count = buffer_count if self.patience is None: self.patience = self.buffer_count self.tables = [pyo.DataTable(buf_size) for _ in range(self.buffer_count)] self.faders = [pyo.Fader(fadein=overlap/SAMPLE_RATE, fadeout=overlap/SAMPLE_RATE, dur=buf_size/SAMPLE_RATE, mul=mul) for _ in range(self.buffer_count)] self.oscs = [pyo.TableRead(t, freq=t.getRate(), mul=f) for t, f in zip(self.tables, self.faders)] self.sum = reduce(lambda a, b: a + b, self.oscs) + add # Timing mechanism to coordinate the tables self.p_metros = [pyo.Metro(time=(self.buffer_count * (buf_size - overlap) / SAMPLE_RATE)) for i in range(self.buffer_count)] self.p_trigs = [pyo.TrigFunc(m, self._play_table, arg=(i)) for i, m in enumerate(self.p_metros)] self.l_trigs = [pyo.TrigFunc(tbr['trig'], self._load_table, arg=(i)) for i, tbr in enumerate(self.oscs)] self._base_objs = self.sum.getBaseObjects()
def i_spectral_pyo(xv,yv): # As i_spectral2 but uses pyo as audio engine ''' # How to use the function # NOTE: there is an instability between pyo and matplotlib when using the # wx-based GUI - graphics MUST be set to False when running in a jupyter notebook import numpy as np import sys,os,re,time sys.path.append('/Users/marco/Dropbox (Personal)/Musica/Applications/musicntwrk') from sonifiPy import * path = './' infile = 'DOSCAR.dat' xv, y = r_1Ddata(path,infile) s,a = i_specral_pyo(xv,y[0],graphics=True) s.start() time.sleep(5) s.stop() ''' nlines = xv.shape[0] nbins = int(np.sqrt(nlines)-np.sqrt(nlines)%1)**2 while nbins > nlines or not(nbins != 0 and ((nbins & (nbins - 1)) == 0)): nbins = int((np.sqrt(nbins)-1)**2) yfft = np.zeros((nbins),dtype=int) for n in range(nbins): yfft[n] = n+1 xminf = xv[0] xmaxf = xv[-1] xvf=np.asarray(xv) xvs = (xv-xminf)/(xmaxf-xminf)*nbins for line in range(nlines): if xvs[line] >= nbins: xvs[line] = -1 xvf[line] = yfft[int(xvs[line])] # Normalization of the data shape into MIDI velocity yminf = min(yv) ymaxf = max(yv) yvf=np.asarray(yv) yvf = (yv-yminf)/(ymaxf-yminf)*127 vel=np.zeros((nbins),dtype=float) nvel=0 for note in range(nbins): for line in range(nlines): if xvf[line] == yfft[note]: vel[nvel] = yvf[line] nvel=nvel+1 break velmax = max(vel) vel /= velmax # FFT for FIR filter ftvel = FFT.irfft(vel) ftvel = FFT.fftshift(ftvel) # start the pyo server s = po.Server().boot() # signal to filter sf = po.PinkNoise(.5) # FIR filter # Create a table of length `buffer size` bs = ftvel.shape[0] # Create a table of length `buffer size` t = po.DataTable(size=bs) osc = po.TableRead(t) # Share the table's memory with a numpy array. arr = np.asarray(t.getBuffer()) # assign ftvel to the table memory buffer arr[:] = ftvel # do the convolution a = po.Convolve(sf, table=t, size=t.getSize(), mul=.5).out() #mix(2).out() return(s,a)
def test_beat1(server): server.server_ms = 0 last_ms = 0 server.last_bpm = 0 server.bpms = [] server.last_avg = 0 def trig_func(): #ct = server.getCurrentTime() delta = server_ms - last_ms last_ms = server_ms #delta = ct - last_ct #bpm = print(delta, 'trig') def time_callback(hours, minutes, seconds, milliseconds): #print(hours, minutes, seconds, milliseconds) server.server_ms = hours * 3600000 + minutes * 60000 + seconds * 1000 + milliseconds def process_callback(): if ad.minthresh != thr.get(): ad.minthresh = thr.get() #if server.last_avg != avg.get(): # print('avg', avg.get()) # server.last_avg = avg.get() return #bpm = 120 / (tmr.get() or 0.001) #while bpm > 360: # bpm /= 2 #while bpm < 40: # bpm *= 2 #print('bpm?', bpm) data = table.getTable() if len(data): #data = [d for d in data if d] #print(len(data), sum(data), server.server_ms) bpm = len(data) * 60 / (sum(data) or 0.001) while bpm > 360: bpm /= 2 while bpm < 40: bpm *= 2 #server.bpms.append() bpm = int(bpm) if bpm != server.last_bpm: server.last_bpm = bpm print('bpm?', bpm) table.reset() #tfl.play() #print(ad.minthresh) server.setTimeCallable(time_callback) server.setCallback(process_callback) table = pyo.DataTable(size=32) inp = pyo.Input([0, 1]) mix = pyo.Mix(inp) flr = pyo.Follower2(mix, 0.5, 0.5) fla = pyo.Average(flr, server.getBufferSize()) #flr.ctrl() spl = pyo.AToDB(flr) thr = spl - 6 ad = pyo.AttackDetector(mix, 0.005, 1000, 12, -30, 0.05) #ad.ctrl() #prn = pyo.Print(ad, 1, message='ad') prn = None tmr = pyo.Timer(ad, ad) #avg = pyo.Average(tmr, server.getBufferSize()) #bpm = 60 / pyo.Min(tmr, 0.001) #trg = pyo.TrigFunc(ad, trig_func) prn2 = pyo.Print(tmr, 1, message='tmr') #tfl = pyo.TableFill(tmr, table) return ad, prn, thr, prn2
def __init__(self, path): self.data, _ = librosa.load(path, sr=SAMPLE_RATE) self.table = pyo.DataTable(self.data.shape[0]) self.player = pyo.TableRead(self.table, freq=self.table.getRate()) self.table.replace(list(self.data))
def __init__(self, master=None, experiment=[], logger=None): ########################### # INIT EXPERIMENT ########################### self.experiment=experiment ########################### # INIT LOGGING ########################### self.logger=logger self.currentTrial = 0 self.currentBlock = 0 self.blockType = 0 self.mouse = 0 ########################### # INIT TIMING ########################### #self.t = timr(1, self.runexperiment) #placeholder to make sure the variable exists self.timers = [] ########################### # INIT VISUAL ########################### self.waitForRatingAnswer = False self.waitForRatingAnswer2 = False self.numRects = 4 self.rects=range(self.numRects) self.screenWidth = 640 self.screenHeight = 480 Frame.__init__(self,master) self.grid() self.userPrompt = StringVar() # moved these up here so they only happen once pianoimage = Image.open(KEYBOARD_IMAGE) self.pianoImage = ImageTk.PhotoImage(pianoimage) sliderimage = Image.open(SLIDER_IMAGE) self.sliderImage = ImageTk.PhotoImage(sliderimage) self.fingerString = StringVar() self.qString = StringVar() self.countString = StringVar() self.create_GUI() ########################### # INIT AUDI ########################### self.s = pyo.Server(buffersize = 8, nchnls = 1) # before booting the server, I'll prompt the user to choose an input device # NOTE: This can be hard-coded later if you always want it to choose a specific MIDI input device # pyo.pm_list_devices() # self.choice = input("Which device will you choose?") # self.s.setMidiInputDevice(int(self.choice)) self.s.setMidiInputDevice(int(3)) self.s.boot() self.s.start() # test = pyo.LFO(freq=440.0).out() time.sleep(1) # settling time # test.stop() # MIDI Stuff self.refnote = 72 self.polynum = 4 self.pianosound = range(self.polynum) self.notes = pyo.Notein(poly=self.polynum, scale=0, mul=0.5) self.enablePlayback = False self.enableNoteLogging = False self.noteTrig = pyo.TrigFunc(self.notes['trigon'],self.onNoteon,range(self.polynum)) #for p in range(polynum): # note trigger mixer self.trigmix = pyo.Mixer(1,self.polynum) for p in range(self.polynum): self.trigmix.addInput(p,self.notes['trigon'][p]) self.trigmix.setAmp(p,0,1.0) self.polyNoteTrig = self.trigmix[0] global midikeymapping # needs to be visible everywhere midikeymapping = 1 # set mapping to 1 to start with # preload sound files self.melodies = [] self.extract = [] for i in range(self.polynum): self.pianosound[i] = pyo.SfPlayer(EXTRACT_DIR + PIANO_FILE[0], speed=1, loop=False, offset=0, interp=2, mul=1, add=0) for fname in STIM_FILES: self.melodies.append(pyo.SfPlayer(STIM_DIR + fname, mul=0.5)) for fname in EXTRACT_FILES: self.extract.append(pyo.SfPlayer(EXTRACT_DIR + fname, mul=0.5)) self.metronome = pyo.SfPlayer(EXTRACT_DIR + METRO_FILE[0], mul=0.5) # prepare sequence and timing triggers # metroSeq launches the metronome self.trialMetroSeq = pyo.Seq(time=NOTEDUR/1000.0, seq=[3,3,3,1], poly=1, onlyonce=True, speed=1) self.expectedKeySeq = pyo.Seq(time=NOTEDUR/1000.0, seq=[9,1,1,1,1], poly=1, onlyonce=True, speed=1) # trialStartTrigger will be manually launched when we want to start a trial self.trialStartTrigger = pyo.Trig().stop() self.warmuptrialStartTrigger = pyo.Trig().stop() self.dummyTrigger = pyo.Trig().stop() self.timerLogsEnabled = False # eventTimer will measure the time between trial events # eventTimer is initially triggered by the trial start, but will later be switched to measure between note events self.trialEventTimer = pyo.Timer(self.polyNoteTrig,self.trialStartTrigger) self.expectedEventTimer = pyo.Timer(self.expectedKeySeq,self.expectedKeySeq) self.timerMeasurement = pyo.DataTable(1) self.lastTimerMeasurement = 0.0 self.expectedMeasurement = pyo.DataTable(1) self.lastExpectedMeasurement = 0.0 self.measurementRecorder = pyo.TablePut(self.trialEventTimer, self.timerMeasurement).play() self.expectedRecorder = pyo.TablePut(self.expectedEventTimer, self.expectedMeasurement).play() self.resetAtStim = False # triggers for the optimized stim delivery self.t1 = pyo.TrigFunc(self.trialStartTrigger,self.playAudioExtract) self.t2 = pyo.TrigFunc(self.trialStartTrigger,self.trialMetroSeq.out) self.t2b = pyo.TrigFunc(self.trialStartTrigger,self.expectedKeySeq.out) self.t3 = pyo.TrigFunc(self.trialMetroSeq,self.playMetronome) # self.t3 = pyo.TrigFunc(self.trialMetroSeq,self.metronome.out) self.t4 = pyo.TrigFunc(self.polyNoteTrig,self.noteTiming) self.t5 = pyo.TrigFunc(self.expectedKeySeq,self.expectedTiming) # triggers for the optimized stim delivery in training #self.t1 = pyo.TrigFunc(self.warmuptrialStartTrigger,self.playAudioExtract) self.t6 = pyo.TrigFunc(self.warmuptrialStartTrigger,self.trialMetroSeq.out) self.t7 = pyo.TrigFunc(self.warmuptrialStartTrigger,self.expectedKeySeq.out) # self.t3 = pyo.TrigFunc(self.trialMetroSeq,self.playMetronome) # self.t3 = pyo.TrigFunc(self.trialMetroSeq,self.metronome.out) # self.t4 = pyo.TrigFunc(self.notes['trigon'],self.noteTiming) # self.t5 = pyo.TrigFunc(self.expectedKeySeq,self.expectedTiming) ########################### # INIT INPUT DEVICES ########################### self.set_keybinds() self.waitForSpacebar = True ############################ self.enableAudioFeedback = False self.QUIT = False self.pause = False