def test_get_contour(self): S = np.array([ [0, 0, 0, 0], [0, 0.002, 0, 0], [1, 0, 5, 0], [0, 0.3, 0.1, 0], [0.1, 0, 0.2, 0], [0, 0.5, 0, 0.002], [0, 0, 0, 0] ]) times = np.array([0.05, 0.1, 0.15, 0.2]) freqs = np.array([97.0, 100.0, 103.0, 105.0, 107.0, 109.0, 112.0]) psh = utils.PeakStreamHelper(S, times, freqs, 0.9, 0.9, 3.456, 80) psh.get_contour() actual_contour_idx = psh.contour_idx expected_contour_idx = [2, 3, 1] self.assertEqual(expected_contour_idx, actual_contour_idx) actual_c_len = psh.c_len expected_c_len = [3] self.assertEqual(expected_c_len, actual_c_len) psh.get_contour() actual_contour_idx = psh.contour_idx expected_contour_idx = [2, 3, 1, 6, 5, 7, 4] self.assertEqual(expected_contour_idx, actual_contour_idx) actual_c_len = psh.c_len expected_c_len = [3, 4] self.assertEqual(expected_c_len, actual_c_len)
def test_peak_streaming(self): S = np.array([ [0, 0, 0, 0], [0, 0.002, 0, 0], [1, 0, 5, 0], [0, 0.3, 0.1, 0], [0.1, 0, 0.2, 0], [0, 0.5, 0, 0.2], [0, 0, 0, 0] ]) times = np.array([0.05, 0.1, 0.15, 0.2]) freqs = np.array([97.0, 100.0, 103.0, 105.0, 107.0, 109.0, 112.0]) psh = utils.PeakStreamHelper(S, times, freqs, 0.9, 0.9, 3.456, 80) expected_c_numbers = np.array([0, 0, 0, 1, 1, 1, 1]) expected_c_times = np.array([0.15, 0.1, 0.05, 0.1, 0.15, 0.2, 0.05]) expected_c_freqs = np.array([103., 105., 103., 109., 107., 109., 107.]) expected_c_sal = np.array([5, 0.3, 1.0, 0.5, 0.2, 0.2, 0.1]) (actual_c_numbers, actual_c_times, actual_c_freqs, actual_c_sal) = psh.peak_streaming() self.assertTrue(np.allclose(expected_c_numbers, actual_c_numbers)) self.assertTrue(np.allclose(expected_c_times, actual_c_times)) self.assertTrue(np.allclose(expected_c_freqs, actual_c_freqs)) self.assertTrue(np.allclose(expected_c_sal, actual_c_sal))
def compute_contours(self, audio_filepath): """Compute contours as in Justin Salamon's melodia. This calls a vamp plugin in the background, which creates a csv file. The csv file is loaded into memory and the file is deleted. Parameters ---------- audio_filepath : str Path to audio file. Returns ------- Instance of Contours object """ if not os.path.exists(audio_filepath): raise IOError( "The audio file {} does not exist".format(audio_filepath) ) if self.preprocess: fpath = self._preprocess_audio( audio_filepath, normalize_format=True, normalize_volume=True ) else: fpath = audio_filepath print("Computing salience...") if self.use_salamon_salience: times, freqs, S = self._compute_salience_salamon(fpath) else: y, sr = librosa.load(fpath, sr=self.audio_samplerate) times, freqs, S = self._compute_salience(y, sr) psh = utils.PeakStreamHelper( S, times, freqs, self.amp_thresh, self.dev_thresh, self.n_gap, self.pitch_cont, peak_thresh=None ) c_numbers, c_times, c_freqs, c_sal = psh.peak_streaming() if len(c_numbers) > 0: c_numbers, c_times, c_freqs, c_sal = self._sort_contours( np.array(c_numbers), np.array(c_times), np.array(c_freqs), np.array(c_sal) ) (c_numbers, c_times, c_freqs, c_sal) = self._postprocess_contours( c_numbers, c_times, c_freqs, c_sal ) return Contours( c_numbers, c_times, c_freqs, c_sal, self.sample_rate, audio_filepath )
def compute_contours(self, salience_npy_file, audio_duration): """Compute contours by peak streaming a salience output. Parameters ---------- salience_npy_file : str Path to precomputed salience numpy file. Returns ------- Instance of Contours object """ if not os.path.exists(salience_npy_file): raise IOError( "The numpy file {} does not exist".format(salience_npy_file)) S = np.load(salience_npy_file) S[S < self.low_amp_thresh] = 0.0 times = self.get_times(S.shape[1]) freqs = self.get_freqs() S[freqs < self.min_contour_freq, :] = 0 S[freqs > self.max_contour_freq, :] = 0 psh = utils.PeakStreamHelper(S, times, freqs, 0, 0, self.n_gap, self.pitch_cont, peak_thresh=self.peak_thresh) c_numbers, c_times, c_freqs, c_sal = psh.peak_streaming() if len(c_numbers) > 0: c_numbers, c_times, c_freqs, c_sal = self._sort_contours( np.array(c_numbers), np.array(c_times), np.array(c_freqs), np.array(c_sal)) (c_numbers, c_times, c_freqs, c_sal) = self._postprocess_contours(c_numbers, c_times, c_freqs, c_sal) return Contours(c_numbers, c_times, c_freqs, c_sal, self.sample_rate, audio_duration=audio_duration)
def test_get_closest_peak(self): S = np.array([ [0, 0, 0, 0], [0, 0.002, 0, 0], [1, 0, 5, 0], [0, 0.3, 0.1, 0], [0.1, 0, 0.2, 0], [0, 0.5, 0, 0.2], [0, 0, 0, 0] ]) times = np.array([0.05, 0.1, 0.15, 0.2]) freqs = np.array([97.0, 100.0, 103.0, 105.0, 107.0, 109.0, 112.0]) psh = utils.PeakStreamHelper(S, times, freqs, 0.9, 0.9, 3.456, 80) actual = psh.get_closest_peak(237.2, [2, 4, 5]) expected = 2 self.assertEqual(expected, actual)
def setUp(self): self.S = np.array([ [0, 0, 0], [1, 0, 5], [0, 0.002, 1], [0.1, 0, 0], [0, 0, 0] ]) self.times = np.array([0.0, 0.5, 1.0]) self.freqs = np.array([10., 100., 150., 200., 300.]) self.amp_thresh = 0.9 self.dev_thresh = 0.9 self.n_gap = 3.234 self.pitch_cont = 80 self.psh = utils.PeakStreamHelper( self.S, self.times, self.freqs, self.amp_thresh, self.dev_thresh, self.n_gap, self.pitch_cont )
def test_update_largest_peak_list(self): S = np.array([ [0, 0, 0, 0], [0, 0.002, 0, 0], [1, 0, 5, 0], [0, 0.3, 0.1, 0], [0.1, 0, 0.2, 0], [0, 0.5, 0, 0.2], [0, 0, 0, 0] ]) times = np.array([0.05, 0.1, 0.15, 0.2]) freqs = np.array([97.0, 100.0, 103.0, 105.0, 107.0, 109.0, 112.0]) psh = utils.PeakStreamHelper(S, times, freqs, 0.9, 0.9, 3.456, 80) expected_avail = np.array([True, True, True, True]) actual_avail = psh.good_peaks_sorted_avail self.assertTrue(np.allclose(expected_avail, actual_avail)) expected_smallest_idx = 0 actual_smallest_idx = psh.smallest_good_peak_idx self.assertEqual(expected_smallest_idx, actual_smallest_idx) psh.update_largest_peak_list(1) expected_avail = np.array([True, False, True, True]) actual_avail = psh.good_peaks_sorted_avail self.assertTrue(np.allclose(expected_avail, actual_avail)) expected_smallest_idx = 0 actual_smallest_idx = psh.smallest_good_peak_idx self.assertEqual(expected_smallest_idx, actual_smallest_idx) psh.update_largest_peak_list(2) expected_avail = np.array([False, False, True, True]) actual_avail = psh.good_peaks_sorted_avail self.assertTrue(np.allclose(expected_avail, actual_avail)) expected_smallest_idx = 2 actual_smallest_idx = psh.smallest_good_peak_idx self.assertEqual(expected_smallest_idx, actual_smallest_idx)
def test_get_peak_candidates3(self): S = np.array([ [0, 0, 0, 0], [0, 0.002, 0, 0], [1, 0, 5, 0], [0, 0.3, 0.1, 0], [0.1, 0, 0.2, 0], [0, 0.5, 0, 0.002], [0, 0, 0, 0] ]) times = np.array([0.05, 0.1, 0.15, 0.2]) freqs = np.array([97.0, 100.0, 103.0, 105.0, 107.0, 109.0, 112.0]) psh = utils.PeakStreamHelper(S, times, freqs, 0.9, 0.9, 3.456, 80) frame_idx = 3 f0_val = 0 expected_cands = None expected_from_good = None actual_cands, actual_from_good = psh.get_peak_candidates( frame_idx, f0_val ) self.assertEqual(expected_cands, actual_cands) self.assertEqual(expected_from_good, actual_from_good)