def get_file_bpm(path, params=None): """ Calculate the beats per minute (bpm) of a given file. path: path to the file param: dictionary of parameters """ if params is None: params = {} # default: samplerate, win_s, hop_s = 44100, 1024, 512 if 'mode' in params: if params.mode in ['super-fast']: # super fast samplerate, win_s, hop_s = 4000, 128, 64 elif params.mode in ['fast']: # fast samplerate, win_s, hop_s = 8000, 512, 128 elif params.mode in ['default']: pass else: print("unknown mode {:s}".format(params.mode)) # manual settings if 'samplerate' in params: samplerate = params.samplerate if 'win_s' in params: win_s = params.win_s if 'hop_s' in params: hop_s = params.hop_s s = source(path, samplerate, hop_s) samplerate = s.samplerate o = tempo("specdiff", win_s, hop_s, samplerate) # List of beats, in samples beats = [] # Total number of frames read total_frames = 0 while True: samples, read = s() is_beat = o(samples) if is_beat: this_beat = o.get_last_s() beats.append(this_beat) #if o.get_confidence() > .2 and len(beats) > 2.: # break total_frames += read if read < hop_s: break def beats_to_bpm(beats, path): # if enough beats are found, convert to periods then to bpm if len(beats) > 1: if len(beats) < 4: print("few beats found in {:s}".format(path)) bpms = 60./diff(beats) return median(bpms) else: print("not enough beats found in {:s}".format(path)) return 0 return beats_to_bpm(beats, path)
def __init__(self, filename, samplerate=44100, win_s=1024, hop_s=512): ''' ''' self.source = source(filename, samplerate, hop_s) self.win_s = win_s self.hop_s = hop_s
def onset(self, **options): onsetAlgorithm = options.get("onsetAlgorithm") or "default" onsetThreshold = options.get("onsetThreshold") or -90 sourceBuffer = source(self.audioFilename, self.samplerate, self.hopSize) onsetSampler = aubio_onset(onsetAlgorithm, self.fftWindowSize, self.hopSize, self.samplerate) # onsetSampler = aubio_level_detection(-70) # list of onsets, in samples onsets = [] timings = [] frames = [] # total number of frames read totalFrames = 0 while True: samples, read = sourceBuffer() if onsetSampler(samples): # print "%f" % onsetSampler.get_last_s() timings.append(onsetSampler.get_last_s()) frames += [totalFrames] onsets.append(onsetSampler.get_last()) totalFrames += read if read < self.hopSize: break return { "timings": timings, "frames": frames, "onsets": onsets }
def pitches(filename, samplerate=None, downsample=1): if samplerate is None: samplerate = 44100 / downsample win_s = 4096 / downsample # fft size hop_s = 512 / downsample # hop size s = aubio.source(filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 pitch_o = aubio.pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit("midi") pitch_o.set_tolerance(tolerance) pitches = [] confidences = [] # total number of frames read total_frames = 0 while True: samples, read = s() pitch = pitch_o(samples)[0] #pitch = int(round(pitch)) confidence = pitch_o.get_confidence() #if confidence < 0.8: pitch = 0. #print "%f %f %f" % (total_frames / float(samplerate), pitch, confidence) pitches += [pitch] confidences += [confidence] total_frames += read if read < hop_s: break return samples, pitches, confidences, total_frames
def mfcc(self, **options): nFilters = options.get("nFilters") or 40 # must be 40 for mfcc nCoeffs = options.get("nCoefs") or 13 sourceBuffer = source(self.audioFilename, self.samplerate, self.hopSize) pvocBuffer = pvoc(self.fftWindowSize, self.hopSize) mfccBuffer = mfcc(self.fftWindowSize, nFilters, nCoeffs, self.samplerate) mfccs = np.zeros([nCoeffs, ]) timings = [] frames = [] totalFrames = 0 while True: samples, read = sourceBuffer() spec = pvocBuffer(samples) mfcc_out = mfccBuffer(spec) mfccs = np.vstack((mfccs, mfcc_out)) totalFrames += read timings += [float(totalFrames) / self.samplerate] frames += [totalFrames] if read < self.hopSize: break return mfccs
def getPitch(filename): from aubio import pitch downsample = 1 samplerate = 44100 / downsample win_s = 1024 / downsample # fft size hop_s = 256/ downsample # hop size s = source(filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 pitch_o = pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit("midi") pitch_o.set_tolerance(tolerance) total_frames = 0 pitches = [] confidences=[] while True: samples, read = s() pitch = pitch_o(samples)[0] confidence = pitch_o.get_confidence() confidences+=[confidence] pitches += [pitch] total_frames += read if read < hop_s: break pitches = array(pitches[1:]) confidences = array(confidences[1:]) cleaned_pitches = pitches cleaned_pitches = ma.masked_where(confidences < tolerance, cleaned_pitches,copy=False) cleaned_pitches = cleaned_pitches[~cleaned_pitches.mask] return max(cleaned_pitches)
def extract_beats (self): samplerate, win_s, hop_s = 44100, 1024, 512 s = aubio.source('good_test.wav', 44100, 512) o = aubio.tempo("specdiff", self.win_s, self.hop_s, self.rate) self._beats = [] total_frames = 0 i = 0 print "Starting extraction ..." while True: samples = self._waveform [i*self.hop_s:(i+1)*self.hop_s] samples = np.float32(samples) is_beat = o (samples) if is_beat: this_beat = o.get_last_s() print this_beat self._beats.append(this_beat) i += 1 if (i+1)*self.hop_s > len(self._waveform): break #bpms = 60./np.diff(self._beats) print "Beats:" print self._beats print "--- BMP:" b = 60./np.diff(self._beats) self._bpm = np.median(b) print self._bpm
def tempo_ext(filename): win_s = 512 # fft size hop_s = win_s / 2 # hop size samplerate = 11000 s = source(filename, samplerate, hop_s) samplerate = s.samplerate o = tempo("default", win_s, hop_s, samplerate) # tempo detection delay, in samples # default to 4 blocks delay to catch up with delay = 4.0 * hop_s # list of beats, in samples beats = [] # total number of frames read total_frames = 0 while True: samples, read = s() is_beat = o(samples) if is_beat: this_beat = int(total_frames - delay + is_beat[0] * hop_s) # print "%f" % (this_beat / float(samplerate)) beats.append(this_beat) total_frames += read if read < hop_s: break # convert samples to seconds beats = map(lambda x: x / float(samplerate), beats) bpms = [60.0 / (b - a) for a, b in zip(beats[:-1], beats[1:])] print "BPM: ", median(bpms) * 4
def getBmp(path, params={}): try: win_s = params['win_s'] samplerate = params['samplerate'] hop_s = params['hop_s'] except: #default: samplerate, win_s, hop_s = 44100, 1024, 512 s = source(path, samplerate, hop_s) samplerate = s.samplerate o = tempo("specdiff", win_s, hop_s, samplerate) #list of beats, in samples beats = [] #Total number of frames read total_frames = 0 while True: samples, read = s() is_beat = o(samples) if is_beat: this_beat = o.get_last_s() beats.append(this_beat) total_frames += read if read < hop_s: break bpms = 60./np.diff(beats) b = np.median(bpms) return b
def test_samplerate_hopsize(self, hop_size, samplerate, soundfile): try: f = source(soundfile, samplerate, hop_size) except RuntimeError as e: self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e))) assert f.samplerate != 0 self.read_from_source(f)
def test_close_file_twice(self): samplerate = 0 # use native samplerate hop_size = 256 for p in list_of_sounds: f = source(p, samplerate, hop_size) f.close() f.close()
def aubiodata(filename, onsetType, threshold, silence): win_s = 512 # fft size hop_s = win_s / 2 # hop size samplerate = 0 # Just an initial setting # threshold = 0.8 # silence = -10 s = source(filename, samplerate, hop_s) samplerate = s.samplerate o = onset(onsetType, win_s, hop_s, samplerate) o.set_threshold(threshold) o.set_silence(silence) # list of onsets, in seconds onsets = [] # total number of frames read total_frames = 0 while True: samples, read = s() if o(samples): # print "%f" % o.get_last_s() onsets.append(o.get_last_s()) total_frames += read if read < hop_s: break # 'onsets' holds, at each entry, the time where an onset is detected (in seconds). return onsets
def apply_filter(path): from aubio import source, sink, digital_filter from os.path import basename, splitext # open input file, get its samplerate s = source(path) samplerate = s.samplerate # create an A-weighting filter f = digital_filter(7) f.set_a_weighting(samplerate) # alternatively, apply another filter # create output file o = sink("filtered_" + splitext(basename(path))[0] + ".wav", samplerate) total_frames = 0 while True: samples, read = s() filtered_samples = f(samples) o(filtered_samples, read) total_frames += read if read < s.hop_size: break duration = total_frames / float(samplerate) print ("read {:s}".format(s.uri)) print ("applied A-weighting filtered ({:d} Hz)".format(samplerate)) print ("wrote {:s} ({:.2f} s)".format(o.uri, duration))
def getPitchDiff(path): downsample = 1 samplerate = 44100 / downsample win_s = 4096 / downsample # fft size hop_s = 512 / downsample # hop size s = source(path, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 pitch_o = aubio.pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit("midi") pitch_o.set_tolerance(tolerance) pitches = [] confidences = [] # total number of frames read total_frames = 0 while True: samples, read = s() pitch = pitch_o(samples)[0] #pitch = int(round(pitch)) confidence = pitch_o.get_confidence() #if confidence < 0.8: pitch = 0. #print "%f %f %f" % (total_frames / float(samplerate), pitch, confidence) pitches += [pitch] confidences += [confidence] total_frames += read if read < hop_s: break return np.median(np.fabs(np.diff(pitches)))
def vocoder(file_id): in_file = '/tmp/don_robot/output/' + file_id + ".mp3" out_file = '/tmp/don_robot/output/' + file_id + "-voc.mp3" samplerate = 44100 f = source(in_file, samplerate, 256) g = sink(out_file, samplerate) total_frames, read = 0, 256 win_s = 512 # fft size hop_s = win_s // 2 # hop size pv = pvoc(win_s, hop_s) # phase vocoder while read: samples, read = f() spectrum = pv(samples) # compute spectrum spectrum.norm *= .5 # reduce amplitude a bit .8 spectrum.phas[:] = 0. # zero phase new_samples = pv.rdo(spectrum) # compute modified samples g(new_samples, read) # write to output total_frames += read format_str = "read {:d} samples from {:s}, written to {:s}" print(format_str.format(total_frames, f.uri, g.uri)) return out_file
def getMelEnergy(path): win_s = 512 #fft size hop_s = win_s / 4 #hop size samplerate = 0 s = source(path, samplerate, hop_s) samplerate = s.samplerate pv = pvoc(win_s, hop_s) f = filterbank(40, win_s) f.set_mel_coeffs_slaney(samplerate) energies = np.zeros((40, )) o = {} total_frames = 0 downsample = 2 while True: samples, read = s() fftgrain = pv(samples) new_energies = f(fftgrain) energies = np.vstack([energies, new_energies]) total_frames += read if read < hop_s: break return energies
def get_waveform_plot(filename, samplerate = 0, block_size = 4096, ax = None, downsample = 2**4): import matplotlib.pyplot as plt if not ax: fig = plt.figure() ax = fig.add_subplot(111) hop_s = block_size allsamples_max = zeros(0,) downsample = downsample # to plot n samples / hop_s a = source(filename, samplerate, hop_s) # source file if samplerate == 0: samplerate = a.samplerate total_frames = 0 while True: samples, read = a() # keep some data to plot it later new_maxes = (abs(samples.reshape(hop_s//downsample, downsample))).max(axis=0) allsamples_max = hstack([allsamples_max, new_maxes]) total_frames += read if read < hop_s: break allsamples_max = (allsamples_max > 0) * allsamples_max allsamples_max_times = [ ( float (t) / downsample ) * hop_s for t in range(len(allsamples_max)) ] ax.plot(allsamples_max_times, allsamples_max, '-b') ax.plot(allsamples_max_times, -allsamples_max, '-b') ax.axis(xmin = allsamples_max_times[0], xmax = allsamples_max_times[-1]) set_xlabels_sample2time(ax, allsamples_max_times[-1], samplerate) return ax
def apply_filter(path, target): # open input file, get its samplerate s = aubio.source(path) samplerate = s.samplerate # create an A-weighting filter f = aubio.digital_filter(7) f.set_a_weighting(samplerate) # create output file o = aubio.sink(target, samplerate) total_frames = 0 while True: # read from source samples, read = s() # filter samples filtered_samples = f(samples) # write to sink o(filtered_samples, read) # count frames read total_frames += read # end of file reached if read < s.hop_size: break # print some info duration = total_frames / float(samplerate) input_str = "input: {:s} ({:.2f} s, {:d} Hz)" output_str = "output: {:s}, A-weighting filtered ({:d} frames total)" print(input_str.format(s.uri, duration, samplerate)) print(output_str.format(o.uri, total_frames))
def test_wrong_seek_too_large(self): f = source(self.default_test_sound) try: with self.assertRaises(ValueError): f.seek(f.duration + f.samplerate * 10) except AssertionError: self.skipTest('seeking after end of stream failed raising ValueError')
def read_pitch(filename, chunk): win_s = chunk # fft size hop_s = win_s # hop size samplerate = 0 # if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) s = source(filename, samplerate, hop_s) samplerate = s.samplerate pitch_o = pitch("default", win_s, hop_s, samplerate) pitch_o.set_unit("freq") pitches = [] # times = [] # total number of frames read total_frames = 0 while True: samples, read = s() cur_pitch = pitch_o(samples)[0] # print "%f %f" % (total_frames / float(samplerate), pitch) pitches.append(Pitch(cur_pitch, total_frames / float(samplerate))) total_frames += read if read < hop_s: break # print pitches if len(pitches) == 0: return None return pitches
def get_file_bpm(self, path): """ Calculate the beats per minute (bpm) of a given file. path: path to the file buf_size length of FFT hop_size number of frames between two consecutive runs samplerate sampling rate of the signal to analyze """ samplerate, buf_size, hop_size = bpm_slider_settings[ BPMOptionsPage.config.setting["bpm_slider_parameter"]] mediasource = source(path.encode("utf-8"), samplerate, hop_size) samplerate = mediasource.samplerate beattracking = tempo("specdiff", buf_size, hop_size, samplerate) # List of beats, in samples beats = [] # Total number of frames read total_frames = 0 while True: samples, read = mediasource() is_beat = beattracking(samples) if is_beat: this_beat = beattracking.get_last_s() beats.append(this_beat) total_frames += read if read < hop_size: break # Convert to periods and to bpm bpms = 60. / diff(beats) return median(bpms)
def decoder(fname): s = aubio.source(fname, samplerate, hop) frames = [] while True: samples, reads = s() if reads == 0: break frames.extend(samples[0:reads]) #print len(frames) max_amp = max(frames) #print max_amp for i in range(0, len(frames)): frames[i] = frames[i]/max_amp #print max(frames) start = 0 while frames[start] < 0.3: start = start+1 end = len(frames)-1 while frames[end] < 0.3: end = end-1 samples = frames[start:end] #print max(samples) x = 0 #print len(samples) freqs = [] while x + 2048 < len(samples): freqs.append(find_freq(samples[x+20:x+20 + 2048])) # print "-----------" x = x + 2205 # print freqs base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' bits = '' for x in freqs: y = x[0] z = x[1] b64 = (y-400)/50 b642 = (z-4500)/50 bits = bits + base64[b64] + base64[b642] # print len(bits)*6/8 return bits
def test_wrong_samplerate(self): for p in list_of_sounds: try: f = source(p, -1) except ValueError, e: pass else: self.fail('negative samplerate does not raise ValueError')
def test_wrong_hop_size(self): for p in list_of_sounds: try: f = source(p, 0, -1) except ValueError, e: pass else: self.fail('negative hop_size does not raise ValueError')
def test_wrong_hop_size(self): for p in list_of_sounds: try: f = source(p, 0, -1) except Exception, e: print e else: self.fail('does not fail with wrong hop_size %d' % f.hop_size)
def test_wrong_samplerate(self): for p in list_of_sounds: try: f = source(p, -1) except Exception, e: print e else: self.fail('does not fail with wrong samplerate')
def open_audio_source(input_wav): """ Open the audio source file `input_wav` and return a tuple with - the aubio source object - its samplerate """ s = aubio.source(input_wav, 0, HOP_S) samplerate = s.samplerate return s, samplerate
def test_duration(self, p): total_frames = 0 f = source(p) duration = f.duration while True: _, read = f() total_frames += read if read < f.hop_size: break self.assertEqual(duration, total_frames)
def analyzePitch(grain): s = source(grain["file"], int(grain["sampleRate"]), int(float(grain["frameCount"]))) samplerate = s.samplerate tolerance = 0.8 pitch_out = pitch("yin", int(float(grain["frameCount"])), int(float(grain["frameCount"])), samplerate) samples, read = s() pitchFreq = pitch_out(samples)[0].item() del s return pitchFreq
def get_spectrogram(filename, samplerate=0): win_s = 512 # fft window size hop_s = win_s // 2 # hop size fft_s = win_s // 2 + 1 # spectrum bins a = source(filename, samplerate, hop_s) # source file if samplerate == 0: samplerate = a.samplerate pv = pvoc(win_s, hop_s) # phase vocoder specgram = zeros([0, fft_s], dtype=float_type) # numpy array to store spectrogram # analysis while True: samples, read = a() # read file specgram = vstack((specgram, pv(samples).norm)) # store new norm vector if read < a.hop_size: break # plotting fig = plt.imshow(log10(specgram.T + .001), origin='bottom', aspect='auto', cmap=plt.cm.gray_r) ax = fig.axes ax.axis([0, len(specgram), 0, len(specgram[0])]) # show axes in Hz and seconds time_step = hop_s / float(samplerate) total_time = len(specgram) * time_step outstr = "total time: %0.2fs" % total_time print(outstr + ", samplerate: %.2fkHz" % (samplerate / 1000.)) n_xticks = 10 n_yticks = 10 def get_rounded_ticks(top_pos, step, n_ticks): top_label = top_pos * step # get the first label ticks_first_label = top_pos * step / n_ticks # round to the closest .1 ticks_first_label = round(ticks_first_label * 10.) / 10. # compute all labels from the first rounded one ticks_labels = [ticks_first_label * n for n in range(n_ticks)] + [top_label] # get the corresponding positions ticks_positions = [ticks_labels[n] / step for n in range(n_ticks)] + [top_pos] # convert to string ticks_labels = ["%.1f" % x for x in ticks_labels] # return position, label tuple to use with x/yticks return ticks_positions, ticks_labels # apply to the axis x_ticks, x_labels = get_rounded_ticks(len(specgram), time_step, n_xticks) y_ticks, y_labels = get_rounded_ticks(len(specgram[0]), (samplerate / 1000. / 2.) / len(specgram[0]), n_yticks) ax.set_xticks(x_ticks) ax.set_yticks(y_ticks) ax.set_xticklabels(x_labels) ax.set_yticklabels(y_labels) ax.set_ylabel('Frequency (kHz)') ax.set_xlabel('Time (s)') ax.set_title(os.path.basename(filename)) for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize('x-small') return fig
def calculate_song_bpm(path: str, params: typing.Dict = None): path = f'{DATA_FOLDER}/{path}' if params is None: params = {} # default: samplerate, win_s, hop_s = 44100, 1024, 512 if 'mode' in params: if params.mode in ['super-fast']: # super fast samplerate, win_s, hop_s = 4000, 128, 64 elif params.mode in ['fast']: # fast samplerate, win_s, hop_s = 8000, 512, 128 elif params.mode in ['default']: pass else: print("unknown mode {:s}".format(params.mode)) # manual settings if 'samplerate' in params: samplerate = params.samplerate if 'win_s' in params: win_s = params.win_s if 'hop_s' in params: hop_s = params.hop_s s = source(path, samplerate, hop_s) samplerate = s.samplerate o = tempo("specdiff", win_s, hop_s, samplerate) # List of beats, in samples beats = [] # Total number of frames read total_frames = 0 while True: samples, read = s() is_beat = o(samples) if is_beat: this_beat = o.get_last_s() beats.append(this_beat) #if o.get_confidence() > .2 and len(beats) > 2.: # break total_frames += read if read < hop_s: break def beats_to_bpm(beats, path): if len(beats) > 1: if len(beats) < 4: print("few beats found in {:s}".format(path)) bpms = 60. / diff(beats) #bpm is an array medinbpm = median(bpms) #medinbpm is a float number return medinbpm #needs to be understood else: print("not enough beats found in {:s}".format(path)) return 0 # print "beats-in-bpm: ", beats return beats_to_bpm(beats, path)
def read_file_aubio(filename): import aubio f = aubio.source(filename, hop_size = 1024) total_frames = 0 while True: _, read = f() total_frames += read if read < f.hop_size: break return total_frames, f.samplerate
def get_spectrogram(filename, samplerate = 0): win_s = 512 # fft window size hop_s = win_s // 2 # hop size fft_s = win_s // 2 + 1 # spectrum bins a = source(filename, samplerate, hop_s) # source file if samplerate == 0: samplerate = a.samplerate pv = pvoc(win_s, hop_s) # phase vocoder specgram = zeros([0, fft_s], dtype=float_type) # numpy array to store spectrogram # analysis while True: samples, read = a() # read file specgram = vstack((specgram,pv(samples).norm)) # store new norm vector if read < a.hop_size: break # plotting fig = plt.imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=plt.cm.gray_r) ax = fig.axes ax.axis([0, len(specgram), 0, len(specgram[0])]) # show axes in Hz and seconds time_step = hop_s / float(samplerate) total_time = len(specgram) * time_step outstr = "total time: %0.2fs" % total_time print(outstr + ", samplerate: %.2fkHz" % (samplerate / 1000.)) n_xticks = 10 n_yticks = 10 def get_rounded_ticks( top_pos, step, n_ticks ): top_label = top_pos * step # get the first label ticks_first_label = top_pos * step / n_ticks # round to the closest .1 ticks_first_label = round ( ticks_first_label * 10. ) / 10. # compute all labels from the first rounded one ticks_labels = [ ticks_first_label * n for n in range(n_ticks) ] + [ top_label ] # get the corresponding positions ticks_positions = [ ticks_labels[n] / step for n in range(n_ticks) ] + [ top_pos ] # convert to string ticks_labels = [ "%.1f" % x for x in ticks_labels ] # return position, label tuple to use with x/yticks return ticks_positions, ticks_labels # apply to the axis x_ticks, x_labels = get_rounded_ticks ( len(specgram), time_step, n_xticks ) y_ticks, y_labels = get_rounded_ticks ( len(specgram[0]), (samplerate / 1000. / 2.) / len(specgram[0]), n_yticks ) ax.set_xticks( x_ticks ) ax.set_yticks ( y_ticks ) ax.set_xticklabels( x_labels ) ax.set_yticklabels ( y_labels ) ax.set_ylabel('Frequency (kHz)') ax.set_xlabel('Time (s)') ax.set_title(os.path.basename(filename)) for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize('x-small') return fig
def get_pitch(self): if path.exists(self.filename) == False: raise Exception(f"File Path to {self.filename} does not exist") else: downsample = 1 samplerate = 44100 // downsample if len(sys.argv) > 2: samplerate = int(sys.argv[2]) win_s = 4096 // downsample # fft size hop_s = 512 // downsample # hop size s = source(self.filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 pitch_o = pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit("midi") pitch_o.set_tolerance(tolerance) pitches = [] confidences = [] # Total number of frames read total_frames = 0 while True: samples, read = s() pitch_midi = pitch_o(samples)[0] pitch_midi = int(round(pitch_midi)) confidence = pitch_o.get_confidence() if confidence < 0.9: pitch_midi = 0. #print("%f %f %f" % (total_frames / float(samplerate), pitch, confidence)) if len(pitches) == 0 and pitch_midi != 0: pitches.append(pitch_midi) elif len(pitches) > 0: if pitch_midi != pitches[-1] and pitch_midi != 0: pitches.append(pitch_midi) else: pass #print(pitches) confidences += [confidence] total_frames += read if read < hop_s: break if 0: sys.exit(0) notes = [] for midi in pitches: note = midi2note(midi) notes.append(note.strip("0123456789")) print(notes) self.pitch_text = str(notes) self.q.put(notes) raise Exception("Thread Terminated")
def disp(filename, samplerate = 44100, tuning = None): from aubio import source, pitch from numpy import mean, std # READ SETUP unit = "cent" downsample = 1 samplerate //= downsample win_s = 4096 // downsample # fft size hop_s = 512 // downsample # hop size s = source(filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 pitch_o = pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit(unit) pitch_o.set_tolerance(tolerance) pitches = [] confidences = [] # READING while True: samples, read = s() pitch = pitch_o(samples)[0] confidence = pitch_o.get_confidence() pitches += [pitch] confidences += [confidence] if read < hop_s: break # OUTPUT if type(tuning) is str: tuning = nameNote(tuning) mistakes = {} for i, pitch in enumerate(pitches): if confidences[i] > 0.1: correct = int(pitch + 0.5) #### CENT/MIDI ONLY #### if correct > 0: if not correct in mistakes: mistakes[correct] = [] mistakes[correct].append(pitch - correct) offset = 0 if tuning != None: offset = mean(mistakes[tuning]) means = {i:100 * (mean(mistakes[i]) - offset) for i in mistakes} stds = {i:100 * std(mistakes[i]) for i in mistakes} print({i:len(mistakes[i]) for i in sorted(mistakes)}) return "\n".join([noteName(i) + ": " + "%.2f" % abs(means[i]) + " cents " + ["flat", "sharp"][means[i] > 0] + ", " + "%.2f" % stds[i] + " cents variation" for i in sorted(mistakes)])
def play(file_name, handle_beat, sample_rate=0): win_s = 1024 # fft size hop_s = win_s // 2 # hop size a_source = aubio.source(file_name, sample_rate, hop_s) # create aubio source sample_rate = a_source.samplerate # create aubio tempo detection a_tempo = aubio.tempo("default", win_s, hop_s, sample_rate) global last_beat_time last_beat_time = time.time() # pyaudio callback def callback(_in_data, _frame_count, _time_info, _status): samples, read = a_source() is_beat = a_tempo(samples) global last_beat_time now = time.time() if is_beat: beat_length = now - last_beat_time last_beat_time = now print("tick") t = threading.Thread(target=handle_beat, args=[beat_length]) t.start() audiobuf = samples.tobytes() if read < hop_s: beat_length = now - last_beat_time handle_beat(beat_length) #t = threading.Thread(target=handle_beat, args=[beat_length]) #t.start() return audiobuf, pyaudio.paComplete return audiobuf, pyaudio.paContinue # create pyaudio stream with frames_per_buffer=hop_s and format=paFloat32 p = pyaudio.PyAudio() pyaudio_format = pyaudio.paFloat32 frames_per_buffer = hop_s n_channels = 1 stream = p.open(format=pyaudio_format, channels=n_channels, rate=sample_rate, output=True, frames_per_buffer=frames_per_buffer, stream_callback=callback) # start pyaudio stream stream.start_stream() # wait for stream to finish while stream.is_active(): time.sleep(0.1) # stop pyaudio stream stream.stop_stream() stream.close() # close pyaudio p.terminate()
def audio_to_midi(filename, midioutput, samplerate=44100, downsample=1): samplerate = 44100 // downsample win_s = 512 // downsample # fft size hop_s = 128 // downsample # hop size s = source(filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 notes_o = notes("default", win_s, hop_s, samplerate) print("%8s" % "time","[ start","vel","last ]") # create a midi file mid = MidiFile() track = MidiTrack() mid.tracks.append(track) ticks_per_beat = mid.ticks_per_beat # default: 480 bpm = 120 # default midi tempo tempo = bpm2tempo(bpm) track.append(MetaMessage('set_tempo', tempo=tempo)) track.append(MetaMessage('time_signature', numerator=4, denominator=4)) def frames2tick(frames, samplerate=samplerate): sec = frames / float(samplerate) return int(second2tick(sec, ticks_per_beat, tempo)) last_time = 0 # total number of frames read total_frames = 0 while True: samples, read = s() new_note = notes_o(samples) if (new_note[0] != 0): note_str = ' '.join(["%.2f" % i for i in new_note]) print("%.6f" % (total_frames/float(samplerate)), new_note) delta = frames2tick(total_frames) - last_time if new_note[2] > 0: track.append(Message('note_off', note=int(new_note[2]), velocity=127, time=delta) ) track.append(Message('note_on', note=int(new_note[0]), velocity=int(new_note[1]), time=delta) ) last_time = frames2tick(total_frames) total_frames += read if read < hop_s: break mid.save(midioutput)
def count_samples_in_file(file_path): from aubio import source hopsize = 256 s = source(file_path, 0, hopsize) total_frames = 0 while True: _, read = s() total_frames += read if read < hopsize: break return total_frames
def get_pitches(filename): pitches = [] s = source(filename, SIMPLE_RATE, HOP_SIZE) p = pitch(PITCH_METHOD, FRAME_SIZE, HOP_SIZE, SIMPLE_RATE) while True: samples, read = s() pit = p(samples)[0] pitches += [pit] if read < HOP_SIZE: break return pitches
def test_read_after_close(self): samplerate = 0 # use native samplerate hop_size = 256 f = source(default_test_sound, samplerate, hop_size) read, frames = f() f.close() with assert_raises(RuntimeError): read, frames = f() with assert_raises(RuntimeError): read, frames = f.do_multi()
def test_seek_to_half(self, p): from random import randint f = source(p, 0, 0) assert f.samplerate != 0 assert f.hop_size != 0 a = self.read_from_source(f) c = randint(0, a) f.seek(c) b = self.read_from_source(f) assert a == b + c
def get_spectrogram(filename, samplerate=0): win_s = 512 # fft window size hop_s = win_s / 2 # hop size fft_s = win_s / 2 + 1 # spectrum bins a = source(filename, samplerate, hop_s) # source file if samplerate == 0: samplerate = a.samplerate pv = pvoc(win_s, hop_s) # phase vocoder specgram = zeros([0, fft_s], dtype='float32') # numpy array to store spectrogram # analysis while True: samples, read = a() # read file specgram = vstack( (specgram, pv(samples).norm)) # store new norm vector if read < a.hop_size: break # plotting imshow(log10(specgram.T + .001), origin='bottom', aspect='auto', cmap=cm.gray_r) axis([0, len(specgram), 0, len(specgram[0])]) # show axes in Hz and seconds time_step = hop_s / float(samplerate) total_time = len(specgram) * time_step print "total time: %0.2fs" % total_time, print ", samplerate: %.2fkHz" % (samplerate / 1000.) n_xticks = 10 n_yticks = 10 def get_rounded_ticks(top_pos, step, n_ticks): top_label = top_pos * step # get the first label ticks_first_label = top_pos * step / n_ticks # round to the closest .1 ticks_first_label = round(ticks_first_label * 10.) / 10. # compute all labels from the first rounded one ticks_labels = [ticks_first_label * n for n in range(n_ticks)] + [top_label] # get the corresponding positions ticks_positions = [ticks_labels[n] / step for n in range(n_ticks)] + [top_pos] # convert to string ticks_labels = ["%.1f" % x for x in ticks_labels] # return position, label tuple to use with x/yticks return ticks_positions, ticks_labels # apply to the axis xticks(*get_rounded_ticks(len(specgram), time_step, n_xticks)) yticks(*get_rounded_ticks(len(specgram[0]), (samplerate / 2. / 1000.) / len(specgram[0]), n_yticks)) ylabel('Frequency (kHz)') xlabel('Time (s)')
def main(): parser = aubio_parser() args = parser.parse_args() if 'show_version' in args and args.show_version: sys.stdout.write('aubio version ' + aubio.version + '\n') sys.exit(0) elif 'verbose' in args and args.verbose > 3: sys.stderr.write('aubio version ' + aubio.version + '\n') if 'command' not in args or args.command is None: # no command given, print help and return 1 parser.print_help() sys.exit(1) elif not args.source_uri and not args.source_uri2: sys.stderr.write("Error: a source is required\n") parser.print_help() sys.exit(1) elif args.source_uri2 is not None: args.source_uri = args.source_uri2 try: # open source_uri with aubio.source(args.source_uri, hop_size=args.hop_size, samplerate=args.samplerate) as a_source: # always update args.samplerate to native samplerate, in case # source was opened with args.samplerate=0 args.samplerate = a_source.samplerate # create the processor for this subcommand processor = args.process(args) frames_read = 0 while True: # read new block from source block, read = a_source() # execute processor on this block res = processor(block) # print results for this block if args.verbose > 0: processor.repr_res(res, frames_read, a_source.samplerate) # increment total number of frames read frames_read += read # exit loop at end of file if read < a_source.hop_size: break # flush the processor if needed processor.flush(frames_read, a_source.samplerate) if args.verbose > 1: fmt_string = "read {:.2f}s" fmt_string += " ({:d} samples in {:d} blocks of {:d})" fmt_string += " from {:s} at {:d}Hz\n" sys.stderr.write( fmt_string.format(frames_read / float(a_source.samplerate), frames_read, frames_read // a_source.hop_size + 1, a_source.hop_size, a_source.uri, a_source.samplerate)) except KeyboardInterrupt: sys.exit(1)
def track(fn): sr = 44100 n_fft = 4096 hop_size = 512 tolerance = .8 pitch_o = aubio.pitch('yinfft', n_fft, hop_size, sr) pitch_o.set_unit('midi') pitch_o.set_tolerance(tolerance) strings = [] pitches = [] confidences = [] time_plt = [] pitch_plt = [] s = aubio.source(fn, sr, hop_size) total_frames = 0 while True: samples, read = s() pitch = int(pitch_o(samples)[0]) confidence = pitch_o.get_confidence() time = total_frames / sr # print("%f %f %f" % (time, pitch, confidence)) pitches.append(pitch) confidences.append(confidence) if confidence > .95 and pitch >= 1: time_plt.append(time) pitch_plt.append(pitch) total_frames += read if read < hop_size: break # Processing pitch_plt = np.array(pitch_plt) pitch_median = np.median(pitch_plt[:50]) pitch_plt -= pitch_median time_plt = np.array(time_plt) time_plt -= time_plt[0] strings.append(np.array_str(pitch_plt)[1:pitch_plt.size-1]) # intervals = np.zeros(pitch_plt.size-1) # for j in range(intervals.size): # intervals[j] = pitch_plt[j+1]-pitch_plt[j] #plt.plot(time_plt, pitch_plt) #plt.show() return pitch_plt
def analyzeMFCC(grain): windowSize = int(float(grain["frameCount"])) s = source(grain["file"], int(grain["sampleRate"]), windowSize) sampleRate = s.samplerate p = pvoc(windowSize, windowSize) m = mfcc(windowSize, 40, 13, s.samplerate) samples, read = s() spec = p(samples) mfcc_out = m(spec) mfccs = mfcc_out.tolist() return mfccs
def get_file_bpm(path, params = None): """ Calculate the beats per minute (bpm) of a given file. path: path to the file param: dictionary of parameters """ if params is None: params = {} try: win_s = params['win_s'] samplerate = params['samplerate'] hop_s = params['hop_s'] except KeyError: """ # super fast samplerate, win_s, hop_s = 4000, 128, 64 # fast samplerate, win_s, hop_s = 8000, 512, 128 """ # default: samplerate, win_s, hop_s = 44100, 1024, 512 s = source(path, samplerate, hop_s) samplerate = s.samplerate o = tempo("specdiff", win_s, hop_s, samplerate) # List of beats, in samples beats = [] # Total number of frames read total_frames = 0 while True: samples, read = s() is_beat = o(samples) if is_beat: this_beat = o.get_last_s() beats.append(this_beat) #if o.get_confidence() > .2 and len(beats) > 2.: # break total_frames += read if read < hop_s: break # Convert to periods and to bpm if len(beats) > 1: if len(beats) < 4: print("few beats found in {:s}".format(path)) bpms = 60./diff(beats) for element in bpms: print element bpms2.append(bpms) b = median(bpms) else: b = 0 print("not enough beats found in {:s}".format(path)) return b
def test_read_from_mono(self, filename): total_frames = 0 hop_size = 2048 with source(filename, 0, hop_size) as input_source: assert_equal(input_source.hop_size, hop_size) #assert_equal(input_source.samplerate, samplerate) total_frames = 0 for frames in input_source: total_frames += frames.shape[-1] # check we read as many samples as we expected assert_equal(total_frames, input_source.duration)
def load_aubio(fp): f = aubio.source(fp, hop_size=1024) sig = np.zeros(f.duration, dtype=aubio.float_type) total_frames = 0 while True: samples, read = f() sig[total_frames:total_frames + read] = samples[:read] total_frames += read if read < f.hop_size: break return sig
def data_load_aubio(**kwargs): if 'filename' in kwargs: filename = kwargs['filename'] else: filename = '/home/src/QK/data/sound-arglaaa-2018-10-25/24.wav' samplerate = 0 src = aubio.source(filename, samplerate, channels=1) src.seek(0) return src
def analyzePitch(grain): s = source(grain["file"], int(grain["sampleRate"]), int(float(grain["frameCount"]))) samplerate = s.samplerate tolerance = 0.8 pitch_out = pitch("yin", int(float(grain["frameCount"])), int(float(grain["frameCount"])), samplerate) samples, read = s() pitchFreq = pitch_out(samples)[0].item() return pitchFreq
def get_length_frames(filename, samplerate = 512, hop_size = 256): f = source(filename, samplerate, hop_size) total_frames, read = 0, f.hop_size while read: vec, read = f() total_frames += read if read < f.hop_size: break return total_frames
def play_music(filename, handle_beat, samplerate=0): win_s = 1024 # fft size hop_s = win_s // 2 # hop size #samplerate = 0 #if len(sys.argv) > 2: samplerate = int(sys.argv[2]) # create aubio source a_source = aubio.source(filename, samplerate, hop_s) samplerate = a_source.samplerate # create aubio tempo detection a_tempo = aubio.tempo("default", win_s, hop_s, samplerate) # create a simple click sound click = 0.7 * np.sin( 2. * np.pi * np.arange(hop_s) / hop_s * samplerate / 3000.) # pyaudio callback def pyaudio_callback(_in_data, _frame_count, _time_info, _status): samples, read = a_source() is_beat = a_tempo(samples) if is_beat: #samples += click handle_beat() audiobuf = samples.tobytes() if read < hop_s: return (audiobuf, pyaudio.paComplete) return (audiobuf, pyaudio.paContinue) # create pyaudio stream with frames_per_buffer=hop_s and format=paFloat32 p = pyaudio.PyAudio() pyaudio_format = pyaudio.paFloat32 frames_per_buffer = hop_s n_channels = 1 stream = p.open(format=pyaudio_format, channels=n_channels, rate=samplerate, output=True, frames_per_buffer=frames_per_buffer, stream_callback=pyaudio_callback) # start pyaudio stream stream.start_stream() # wait for stream to finish while stream.is_active(): time.sleep(0.1) # stop pyaudio stream stream.stop_stream() stream.close() stream.get # close pyaudio p.terminate()
def _extract_frequency_bands(self): """ Helper function to extract frequency bands from audio ARGS: None RETURNS: None """ s = source(filename, samplerate, hop_s) samplerate = s.samplerate pass
def test_samplerate_hopsize(self, hop_size, samplerate, soundfile): orig_samplerate = parse_file_samplerate(soundfile) try: if orig_samplerate is not None and orig_samplerate < samplerate: # upsampling should emit a warning with assert_warns(UserWarning): f = source(soundfile, samplerate, hop_size) else: f = source(soundfile, samplerate, hop_size) except RuntimeError as e: err_msg = 'failed opening with hop_s={:d}, samplerate={:d} ({:s})' skipTest(err_msg.format(hop_size, samplerate, str(e))) assert f.samplerate != 0 read_frames = self.read_from_source(f) if 'f_' in soundfile and samplerate == 0: import re f = re.compile(r'.*_\([0:9]*f\)_.*') match_f = re.findall('([0-9]*)f_', soundfile) if len(match_f) == 1: expected_frames = int(match_f[0]) assert_equal(expected_frames, read_frames)
def __init__(self, song, samplerate=44100, hop_size=256): self.src = aubio.source(song) self.total_frames = 0 self.hop_size = hop_size while True: samples, read = self.src() self.total_frames += read if read < self.hop_size: break self.lengthInSecs = self.total_frames / self.src.samplerate
def get_max_time(filename, samplerate=0, block_size=4096, ax=None, downsample=2**4, stop_at=None): import matplotlib.pyplot as plt if not ax: fig = plt.figure() ax = fig.add_subplot(111) hop_s = block_size allsamples = np.zeros(0, ) downsample = downsample # to plot n samples / hop_s should_stop_early = True a = source(filename, samplerate, hop_s) # source file if samplerate == 0: samplerate = a.samplerate if stop_at == None: should_stop_early = False total_frames = 0 while True: samples, read = a() # keep some data to plot it later new_samples = abs(samples) allsamples = np.hstack([allsamples, new_samples]) total_frames += read if total_frames > stop_at * samplerate and should_stop_early: break if read < hop_s: break offset_samples = np.hstack([allsamples[1:], [0]]) derivative_samples = offset_samples - allsamples t_max_idx = np.argmax(allsamples, axis=0) derivative_max_idx = np.argmax(derivative_samples, axis=0) # normalize derivative_samples = derivative_samples / derivative_samples[ derivative_max_idx] allsamples_times = [(float(t)) for t in range(len(allsamples))] t_max = allsamples_times[t_max_idx] derivative_t_max = allsamples_times[derivative_max_idx] print("max is reached at %02d:%02d:%03d" % (t_max / float(samplerate) / 60, (t_max / float(samplerate)) % 60, (t_max * 1000.0 / float(samplerate)) % 1000)) ax.plot(allsamples_times, allsamples, '-b', derivative_samples, '-g') ax.axis(xmin=allsamples_times[0], xmax=allsamples_times[-1]) set_xlabels_sample2time(ax, allsamples_times[-1], samplerate) return ax, t_max / float(samplerate), derivative_t_max / float(samplerate)
def analyse_notes(self): """ Taken from https://github.com/aubio/aubio/tree/master/python/demos and slightly modified This uses the pitch method in aubio. It reads the audio file and gives a list of frequencies and the proability that it is that note. :returns A list of notes and the frequecies of those notes """ downsample = 1 samplerate = 44100 // downsample win_s = 4096 // downsample # fft size hop_s = 512 // downsample # hop size # TAKES A STR ARG FOR THE FILE PATH, NOT THE FILE ITSELF try: s = aubio.source(self.filepath, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 # uses the yin algorithm to determine pitch pitch_o = aubio.pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit("Hz") pitch_o.set_tolerance(tolerance) pitches = [] confidences = [] # total number of frames read total_frames = 0 while True: samples, read = s() pitch = pitch_o(samples)[0] pitch = int(round(pitch)) confidence = pitch_o.get_confidence() # set the threshold high to ignore frequencies such as random string noise before audio start playing if confidence < 0.99: pitch = 0. pitches += [pitch] confidences += [confidence] total_frames += read if read < hop_s: break pitch_list_minus_duplicates, freq_list_minus_duplicates = self.remove_consecutive_duplicates( pitches) return pitch_list_minus_duplicates, freq_list_minus_duplicates except Exception as e: error_str = "Could not open file:{}. Error: {}".format( self.filepath, e) print(error_str)
def detect(filename): downsample = 8 samplerate = 44100 // downsample win_s = 4096 // downsample # fft size hop_s = 512 // downsample # hop size s = aubio.source(filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 pitch_o = aubio.pitch("yin", win_s, hop_s, samplerate) pitch_o.set_unit("freq") pitch_o.set_tolerance(tolerance) pitches = [] confidences = [] # total number of frames read total_frames = 0 counter = 0 while True: samples, read = s() pitch = pitch_o(samples)[0] confidence = pitch_o.get_confidence() #print "%f %f %f" % (total_frames / float(samplerate), pitch, confidence) pitches += [pitch] confidences += [confidence] total_frames += read if read < hop_s: break letterList = [] newPitches = [] amplitudes = [] for index in range(0, len(pitches)): totalFreq = 0 if(index+5 <= len(pitches)): for freq in range(index, index+5): totalFreq += pitches[freq] averageFreq = totalFreq/5 newPitches.append(averageFreq) else: counter = 0 for index in range(index, len(pitches)): totalFreq += pitches[freq] counter += 1 averageFreq = totalFreq/counter newPitches.append(averageFreq) # loudness amp = getSection(filename,index, index + 5) amplitudes.append(amp.rms) for pi in newPitches: letterName = findPitchLetterName(pi) letterList.append(pi) # letterName -> pi for frequency numbers newList = modifyList(letterList) note = findModeInList(newList) #print(letterList, amplitudes) return letterList, amplitudes
def load_file_aubio(filename): import aubio f = aubio.source(filename, hop_size=1024) y = np.zeros(f.duration, dtype=aubio.float_type) total_frames = 0 while True: samples, read = f() y[total_frames:total_frames + read] = samples[:read] total_frames += read if read < f.hop_size: break assert len(y) == total_frames #print y.mean(), y.shape return total_frames, f.samplerate