Mercurial > hg > plosone_underreview
changeset 37:2cc444441f42 branch-tests
refactor pitchbihist and introduce default melody_sr
author | Maria Panteli |
---|---|
date | Thu, 14 Sep 2017 14:50:00 +0100 |
parents | 3b67cd634b9a |
children | e5e8e8a96948 |
files | scripts/PitchBihist.py tests/test_PitchBihist.py |
diffstat | 2 files changed, 28 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/PitchBihist.py Thu Sep 14 14:16:29 2017 +0100 +++ b/scripts/PitchBihist.py Thu Sep 14 14:50:00 2017 +0100 @@ -13,13 +13,9 @@ class PitchBihist: def __init__(self, win2sec=8): - self.y = None - self.sr = None - self.chroma = None - self.chromasr = None - self.melodiasr = 44100. / 128. - self.bihist = None self.win2sec = win2sec + self.hop2sec = 0.5 + self.melody_sr = 44100. / 128. def hz_to_cents(self, freq_Hz, ref_Hz=32.703, n_cents=1200): @@ -42,13 +38,13 @@ return [] data = np.loadtxt(melodia_file, delimiter=',') times, freqs = (data[:, 0], data[:, 1]) - self.chromasr = 1. / (times[1] - times[0]) + #melody_sr = 1. / (times[1] - times[0]) if stop_sec is not None: stop_idx = np.where(times < stop_sec)[0] times, freqs = times[stop_idx], freqs[stop_idx] freqs[freqs<=0] = np.nan melody = freqs - return melody + return melody#, melody_sr def get_melody_matrix(self, melody): @@ -64,15 +60,16 @@ def bihist_from_melodia(self, filename='sample_melodia.csv', secondframedecomp=True, stop_sec=None): + #melody, melody_sr = self.get_melody_from_file(filename, stop_sec=stop_sec) melody = self.get_melody_from_file(filename, stop_sec=stop_sec) if len(melody) == 0: - self.bihist = [] - return self.bihist + return [] melody_matrix = self.get_melody_matrix(melody) + bihist = [] if secondframedecomp: nbins, norigframes = melody_matrix.shape - win2 = int(round(self.win2sec*self.chromasr)) - hop2 = int(round(0.5*self.chromasr)) + win2 = int(round(self.win2sec * self.melody_sr)) + hop2 = int(round(self.hop2sec * self.melody_sr)) if norigframes<=win2: nframes = 1 win2 = norigframes @@ -84,16 +81,19 @@ bihist = self.bihistogram(frame) bihist = np.reshape(bihist, -1) bihistframes[:, i] = bihist - self.bihist = bihistframes + bihist = bihistframes else: - self.bihist = self.bihistogram(melody_matrix) - return self.bihist + bihist = self.bihistogram(melody_matrix) + return bihist - def bihistogram(self, spec, winsec=0.5, align=True): - win = int(round(winsec*self.chromasr)) + def bihistogram(self, spec, spec_sr=None, winsec=0.5, align=True): + if spec_sr is None: + # assume spec is melody_matrix with default sr + spec_sr = self.melody_sr + win = int(round(winsec * spec_sr)) ker = np.concatenate([np.zeros((win, 1)), np.ones((win+1, 1))], axis=0) - spec = spec.T # transpose to have franes as rows in convolution + spec = spec.T # transpose to have frames as rows in convolution # energy threshold thr = 0.3*np.max(spec) @@ -120,54 +120,6 @@ return B - def bihist_from_chroma(self, filename='test.wav', secondframedecomp=True): - self.chroma, self.chromasr = s.get_smoothie_for_bihist(filename=filename, hopinsec=0.005) - if secondframedecomp: - win2 = int(round(8*self.chromasr)) - hop2 = int(round(0.5*self.chromasr)) - nbins, norigframes = self.chroma.shape - if norigframes<win2: - nframes = 1 - else: - nframes = int(1+np.floor((norigframes-win2)/float(hop2))) - bihistframes = np.empty((nbins*nbins, nframes)) - for i in range(nframes): # loop over all 8-sec frames - frame = self.chroma[:, (i*hop2):min((i*hop2+win2),norigframes)] - bihist = self.bihistogram(frame) - bihist = np.reshape(bihist, -1) - bihistframes[:, i] = bihist - self.bihist = bihistframes - else: - self.bihist = np.reshape(self.bihistogram(), -1) - - - def bihist_from_precomp_chroma(self, align=False): - win2 = int(round(self.win2sec*self.chromasr)) - hop2 = int(round(0.5*self.chromasr)) - nbins, norigframes = self.chroma.shape - if norigframes<win2: - nframes = 1 - else: - nframes = int(1+np.floor((norigframes-win2)/float(hop2))) - bihistframes = np.empty((nbins*nbins, nframes)) - for i in range(nframes): # loop over all 8-sec frames - frame = self.chroma[:, (i*hop2):min((i*hop2+win2),norigframes)] - bihist = self.bihistogram(frame, align=align) - bihist = np.reshape(bihist, -1) - bihistframes[:, i] = bihist - self.bihist = bihistframes - - def get_pitchbihist(self, filename='test.wav'): - self.bihist_from_chroma(filename=filename) - return self.bihist - - def get_pitchbihist_from_chroma(self, chroma=[], chromasr=[]): - self.chroma = chroma - self.chromasr = chromasr - self.bihist_from_precomp_chroma(align=False) - return self.bihist - - if __name__ == '__main__': pb = PitchBihist() - pb.get_pitchbihist() + pb.bihist_from_melodia(filename='vamp_melodia.csv')
--- a/tests/test_PitchBihist.py Thu Sep 14 14:16:29 2017 +0100 +++ b/tests/test_PitchBihist.py Thu Sep 14 14:50:00 2017 +0100 @@ -32,7 +32,7 @@ def test_get_melody_from_file(): melodia_file = 'data/sample_dataset/Melodia/mel_1_2_1.csv' melody = pbi.get_melody_from_file(melodia_file) - assert len(melody) < 12. * pbi.chromasr + assert len(melody) < 12. * pbi.melody_sr def test_get_melody_matrix(): @@ -72,4 +72,11 @@ assert bihist[45, 0] > 0 and (np.sum(bihist) - bihist[45, 0]) == 0 - +def test_bihistogram_align(): + melody = np.concatenate([660 * np.ones(250), 440 * np.ones(500)]) + melody_matrix = pbi.get_melody_matrix(melody) + # bin of max magnitude = A = 45/60 + bihist = pbi.bihistogram(melody_matrix, align=True) + # bihist[20, 45] == 0 + # we shift up 45 so rows 20-45 and left 45 so cols 45-45 + assert bihist[20-45, 0] == 1