def test_spectral_centroid_synthetic(): k = 5 def __test(S, freq, sr, n_fft): cent = librosa.feature.spectral_centroid(S=S, freq=freq) if freq is None: freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) assert np.allclose(cent, freq[k]) srand() # construct a fake spectrogram sr = 22050 n_fft = 1024 S = np.zeros((1 + n_fft // 2, 10)) S[k, :] = 1.0 yield __test, S, None, sr, n_fft freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) yield __test, S, freq, sr, n_fft # And if we modify the frequencies freq *= 3 yield __test, S, freq, sr, n_fft # Or if we make up random frequencies for each frame freq = np.random.randn(*S.shape) yield __test, S, freq, sr, n_fft
def __test(metric, bandwidth, self): srand() data = np.random.randn(3, 100) distance = squareform(pdist(data.T, metric=metric)) rec = librosa.segment.recurrence_matrix(data, mode='affinity', metric=metric, sparse=True, bandwidth=bandwidth, self=self) if self: assert np.allclose(rec.diagonal(), 1.0) else: assert np.allclose(rec.diagonal(), 0.0) i, j, vals = scipy.sparse.find(rec) logvals = np.log(vals) # After log-scaling, affinity will match distance up to a constant factor ratio = -logvals / distance[i, j] if bandwidth is None: # Estimate the global bandwidth using non-zero distances assert np.allclose(-logvals, distance[i, j] * np.nanmax(ratio)) else: assert np.allclose(-logvals, distance[i, j] * bandwidth)
def test_roll_sparse(): srand() def __test(fmt, shift, axis, X): X_sparse = X.asformat(fmt) X_dense = X.toarray() Xs_roll = librosa.util.roll_sparse(X_sparse, shift, axis=axis) assert scipy.sparse.issparse(Xs_roll) eq_(Xs_roll.format, X_sparse.format) Xd_roll = librosa.util.roll_sparse(X_dense, shift, axis=axis) assert np.allclose(Xs_roll.toarray(), Xd_roll), (X_dense, Xs_roll.toarray(), Xd_roll) Xd_roll_np = np.roll(X_dense, shift, axis=axis) assert np.allclose(Xd_roll, Xd_roll_np) X = scipy.sparse.lil_matrix(np.random.randint(0, high=10, size=(16, 16))) for fmt in ['csr', 'csc', 'lil', 'dok', 'coo']: for shift in [0, 8, -8, 20, -20]: for axis in [0, 1, -1]: yield __test, fmt, shift, axis, X
def test_stack_memory(): def __test(data, n_steps, delay): data_stack = librosa.feature.stack_memory(data, n_steps=n_steps, delay=delay) # If we're one-dimensional, reshape for testing if data.ndim == 1: data = data.reshape((1, -1)) d, t = data.shape eq_(data_stack.shape[0], n_steps * d) eq_(data_stack.shape[1], t) for i in range(d): for step in range(1, n_steps): assert np.allclose(data[i, :- step * delay], data_stack[step * d + i, step * delay:]) srand() for ndim in [1, 2]: data = np.random.randn(* ([5] * ndim)) for n_steps in [-1, 0, 1, 2, 3, 4]: for delay in [-1, 0, 1, 2, 4]: tf = __test if n_steps < 1: tf = raises(librosa.ParameterError)(__test) if delay < 1: tf = raises(librosa.ParameterError)(__test) yield tf, data, n_steps, delay
def __test(n, pre_max, post_max, pre_avg, post_avg, delta, wait): srand() # Generate a test signal x = np.random.randn(n)**2 peaks = librosa.util.peak_pick(x, pre_max, post_max, pre_avg, post_avg, delta, wait) for i in peaks: # Test 1: is it a peak in this window? s = i - pre_max if s < 0: s = 0 t = i + post_max diff = x[i] - np.max(x[s:t]) assert diff > 0 or np.isclose(diff, 0, rtol=1e-3, atol=1e-4) # Test 2: is it a big enough peak to count? s = i - pre_avg if s < 0: s = 0 t = i + post_avg diff = x[i] - (delta + np.mean(x[s:t])) assert diff > 0 or np.isclose(diff, 0, rtol=1e-3, atol=1e-4) # Test 3: peak separation assert not np.any(np.diff(peaks) <= wait)
def test_spectral_bandwidth_onecol(): # This test checks for issue https://github.com/librosa/librosa/issues/552 # failure when the spectrogram has a single column def __test(S, freq): bw = librosa.feature.spectral_bandwidth(S=S, freq=freq) assert bw.shape == (1, 1) k = 5 srand() # construct a fake spectrogram sr = 22050 n_fft = 1024 S = np.zeros((1 + n_fft // 2, 1)) S[k, :] = 1.0 # With vanilla frequencies yield __test, S, None # With explicit frequencies freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) yield __test, S, freq # And if we modify the frequencies freq = 3 * librosa.fft_frequencies(sr=sr, n_fft=n_fft) yield __test, S, freq # Or if we make up random frequencies for each frame freq = np.random.randn(*S.shape) yield __test, S, freq
def __test(n, k, width, sym, metric): srand() # Make a data matrix data = np.random.randn(3, n) D = librosa.segment.recurrence_matrix(data, k=k, width=width, sym=sym, axis=-1, metric=metric) # First test for symmetry if sym: assert np.allclose(D, D.T) # Test for target-axis invariance D_trans = librosa.segment.recurrence_matrix(data.T, k=k, width=width, sym=sym, axis=0, metric=metric) assert np.allclose(D, D_trans) # If not symmetric, test for correct number of links if not sym and k is not None: real_k = min(k, n - width) assert not np.any(D.sum(axis=1) != real_k) # Make sure the +- width diagonal is hollow # It's easier to test if zeroing out the triangles leaves nothing idx = np.tril_indices(n, k=width) D[idx] = False D.T[idx] = False assert not np.any(D)
def test_cqt_white_noise(): def __test(fmin, n_bins, scale, sr, y): C = np.abs(librosa.cqt(y=y, sr=sr, fmin=fmin, n_bins=n_bins, scale=scale)) if not scale: lengths = librosa.filters.constant_q_lengths(sr, fmin, n_bins=n_bins) C /= np.sqrt(lengths[:, np.newaxis]) # Only compare statistics across the time dimension # we want ~ constant mean and variance across frequencies assert np.allclose(np.mean(C, axis=1), 1.0, atol=2.5e-1), np.mean(C, axis=1) assert np.allclose(np.std(C, axis=1), 0.5, atol=5e-1), np.std(C, axis=1) srand() for sr in [22050]: y = np.random.randn(30 * sr) for scale in [False, True]: for fmin in librosa.note_to_hz(['C1', 'C2']): for n_octaves in range(2, 4): yield __test, fmin, n_octaves * 12, scale, sr, y
def test_hcqt_white_noise(): def __test(fmin, n_bins, scale, sr, y): C = librosa.hybrid_cqt(y=y, sr=sr, fmin=fmin, n_bins=n_bins, scale=scale) if not scale: lengths = librosa.filters.constant_q_lengths(sr, fmin, n_bins=n_bins) C /= np.sqrt(lengths[:, np.newaxis]) assert np.allclose(np.mean(C, axis=1), 1.0, atol=2.5e-1), np.mean(C, axis=1) assert np.allclose(np.std(C, axis=1), 0.5, atol=5e-1), np.std(C, axis=1) srand() for sr in [22050]: y = np.random.randn(30 * sr) for scale in [False, True]: for fmin in librosa.note_to_hz(['C1', 'C2']): for n_octaves in [6, 7]: yield __test, fmin, n_octaves * 12, scale, sr, y
def test_spectral_bandwidth_synthetic(): # This test ensures that a signal confined to a single frequency bin # always achieves 0 bandwidth k = 5 def __test(S, freq, sr, n_fft, norm, p): bw = librosa.feature.spectral_bandwidth(S=S, freq=freq, norm=norm, p=p) assert not np.any(bw) srand() # construct a fake spectrogram sr = 22050 n_fft = 1024 S = np.zeros((1 + n_fft // 2, 10)) S[k, :] = 1.0 for norm in [False, True]: for p in [1, 2]: # With vanilla frequencies yield __test, S, None, sr, n_fft, norm, p # With explicit frequencies freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) yield __test, S, freq, sr, n_fft, norm, p # And if we modify the frequencies freq = 3 * librosa.fft_frequencies(sr=sr, n_fft=n_fft) yield __test, S, freq, sr, n_fft, norm, p # Or if we make up random frequencies for each frame freq = np.random.randn(*S.shape) yield __test, S, freq, sr, n_fft, norm, p
def test_spectral_rolloff_synthetic(): srand() sr = 22050 n_fft = 2048 def __test(S, freq, pct): rolloff = librosa.feature.spectral_rolloff(S=S, sr=sr, freq=freq, roll_percent=pct) if freq is None: freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) idx = np.floor(pct * freq.shape[0]).astype(int) assert np.allclose(rolloff, freq[idx]) S = np.ones((1 + n_fft // 2, 10)) for pct in [0.25, 0.5, 0.95]: # Implicit frequencies yield __test, S, None, pct # Explicit frequencies freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) yield __test, S, freq, pct # And time-varying frequencies freq = np.cumsum(np.abs(np.random.randn(*S.shape)), axis=0) yield __test, S, freq, pct
def __test(n, d, q): srand() X = np.random.randn(*([d] * n))**4 X = np.asarray(X) xs = librosa.util.sparsify_rows(X, quantile=q) if ndim == 1: X = X.reshape((1, -1)) assert np.allclose(xs.shape, X.shape) # And make sure that xs matches X on nonzeros xsd = np.asarray(xs.todense()) for i in range(xs.shape[0]): assert np.allclose(xsd[i, xs[i].indices], X[i, xs[i].indices]) # Compute row-wise magnitude marginals v_in = np.sum(np.abs(X), axis=-1) v_out = np.sum(np.abs(xsd), axis=-1) # Ensure that v_out retains 1-q fraction of v_in assert np.all(v_out >= (1.0 - q) * v_in)
def test_recurrence_badmode(): srand() data = np.random.randn(3, 100) rec = librosa.segment.recurrence_matrix(data, mode='NOT A MODE', metric='sqeuclidean', sparse=True)
def test_lag_to_recurrence_sparse_badaxis(): srand() data = np.random.randn(3, 100) R = librosa.segment.recurrence_matrix(data, sparse=True) L = librosa.segment.recurrence_to_lag(R) librosa.segment.lag_to_recurrence(L, axis=2)
def __test_positional(n): srand() dpos0 = librosa.segment.timelag_filter(pos0_filter) dpos1 = librosa.segment.timelag_filter(pos1_filter, index=1) X = np.random.randn(n, n) assert np.allclose(X, dpos0(X)) assert np.allclose(X, dpos1(None, X))
def __test(P): srand() frame, hop = P y = np.random.randn(8000) y_frame = librosa.util.frame(y, frame_length=frame, hop_length=hop) for i in range(y_frame.shape[1]): assert np.allclose(y_frame[:, i], y[i * hop:(i * hop + frame)])
def test_recurrence_sparse(): srand() data = np.random.randn(3, 100) D_sparse = librosa.segment.recurrence_matrix(data, sparse=True) D_dense = librosa.segment.recurrence_matrix(data, sparse=False) assert scipy.sparse.isspmatrix(D_sparse) assert np.allclose(D_sparse.todense(), D_dense)
def __test(x, y, sparse): srand() X = np.empty((10, 100)) # Build a recurrence matrix, just for testing purposes rec = np.random.randn(x, y) if sparse: rec = scipy.sparse.csr_matrix(rec) librosa.decompose.nn_filter(X, rec=rec)
def test_recurrence_distance(): srand() data = np.random.randn(3, 100) distance = squareform(pdist(data.T, metric='sqeuclidean')) rec = librosa.segment.recurrence_matrix(data, mode='distance', metric='sqeuclidean', sparse=True) i, j, vals = scipy.sparse.find(rec) assert np.allclose(vals, distance[i, j])
def __test(n, pad): srand() data = np.random.randn(17, n) rec = librosa.segment.recurrence_matrix(data) lag = librosa.segment.recurrence_to_lag(rec, pad=pad, axis=-1) lag2 = librosa.segment.recurrence_to_lag(rec.T, pad=pad, axis=0).T rec2 = librosa.segment.lag_to_recurrence(lag) assert np.allclose(rec, rec2) assert np.allclose(lag, lag2)
def test_cross_similarity_multi(): srand() X1 = np.random.randn(2, 10, 100) X2 = np.random.randn(2, 10, 50) R = librosa.segment.cross_similarity(X1, X2, mode='affinity') # This should give the same output as if we stacked out the leading channel X1f = np.concatenate([X1[0], X1[1]], axis=0) X2f = np.concatenate([X2[0], X2[1]], axis=0) Rf = librosa.segment.cross_similarity(X1f, X2f, mode='affinity') assert np.allclose(R, Rf)
def test_nn_filter_mean_rec_sparse(): srand() X = np.random.randn(10, 100) # Build a recurrence matrix, just for testing purposes rec = librosa.segment.recurrence_matrix(X, sparse=True) X_filtered = librosa.decompose.nn_filter(X, rec=rec) # Normalize the recurrence matrix rec = librosa.util.normalize(rec.toarray(), axis=1, norm=1) assert np.allclose(X_filtered, (X.dot(rec.T)))
def test_lag_to_recurrence(n, pad): srand() data = np.random.randn(17, n) rec = librosa.segment.recurrence_matrix(data) lag = librosa.segment.recurrence_to_lag(rec, pad=pad, axis=-1) lag2 = librosa.segment.recurrence_to_lag(rec.T, pad=pad, axis=0).T rec2 = librosa.segment.lag_to_recurrence(lag) assert np.allclose(rec, rec2) assert np.allclose(lag, lag2)
def poly_freq(request): srand() freq = librosa.fft_frequencies() if request.param in (1, 2): return freq**request.param elif request.param == -1: return np.cumsum(np.abs(np.random.randn(1 + 2048 // 2)), axis=0) elif request.param == "varying": return np.cumsum(np.abs(np.random.randn(1 + 2048 // 2, 5)), axis=0) else: return None
def test_normalize(): srand() def __test_pass(X, norm, axis): X_norm = librosa.util.normalize(X, norm=norm, axis=axis) # Shape and dtype checks assert X_norm.dtype == X.dtype assert X_norm.shape == X.shape if norm is None: assert np.allclose(X, X_norm) return X_norm = np.abs(X_norm) if norm == np.inf: values = np.max(X_norm, axis=axis) elif norm == -np.inf: values = np.min(X_norm, axis=axis) elif norm == 0: # XXX: normalization here isn't quite right values = np.ones(1) else: values = np.sum(X_norm**norm, axis=axis)**(1. / norm) assert np.allclose(values, np.ones_like(values)) @raises(librosa.ParameterError) def __test_fail(X, norm, axis): librosa.util.normalize(X, norm=norm, axis=axis) for ndims in [1, 2, 3]: X = np.random.randn(*([16] * ndims)) for axis in range(X.ndim): for norm in [np.inf, -np.inf, 0, 0.5, 1.0, 2.0, None]: yield __test_pass, X, norm, axis for norm in ['inf', -0.5, -2]: yield __test_fail, X, norm, axis # And test for non-finite failure X[0] = np.nan yield __test_fail, X, np.inf, 0 X[0] = np.inf yield __test_fail, X, np.inf, 0 X[0] = -np.inf yield __test_fail, X, np.inf, 0
def test_normalize(): srand() def __test_pass(X, norm, axis): X_norm = librosa.util.normalize(X, norm=norm, axis=axis) # Shape and dtype checks assert X_norm.dtype == X.dtype assert X_norm.shape == X.shape if norm is None: assert np.allclose(X, X_norm) return X_norm = np.abs(X_norm) if norm == np.inf: values = np.max(X_norm, axis=axis) elif norm == -np.inf: values = np.min(X_norm, axis=axis) elif norm == 0: # XXX: normalization here isn't quite right values = np.ones(1) else: values = np.sum(X_norm**norm, axis=axis)**(1./norm) assert np.allclose(values, np.ones_like(values)) @raises(librosa.ParameterError) def __test_fail(X, norm, axis): librosa.util.normalize(X, norm=norm, axis=axis) for ndims in [1, 2, 3]: X = np.random.randn(* ([16] * ndims)) for axis in range(X.ndim): for norm in [np.inf, -np.inf, 0, 0.5, 1.0, 2.0, None]: yield __test_pass, X, norm, axis for norm in ['inf', -0.5, -2]: yield __test_fail, X, norm, axis # And test for non-finite failure X[0] = np.nan yield __test_fail, X, np.inf, 0 X[0] = np.inf yield __test_fail, X, np.inf, 0 X[0] = -np.inf yield __test_fail, X, np.inf, 0
def test_recurrence_sparse(self): srand() data = np.random.randn(3, 100) D_sparse = librosa.segment.recurrence_matrix(data, sparse=True, self=self) D_dense = librosa.segment.recurrence_matrix(data, sparse=False, self=self) assert scipy.sparse.isspmatrix(D_sparse) assert np.allclose(D_sparse.todense(), D_dense) if self: assert np.allclose(D_sparse.diagonal(), True) else: assert np.allclose(D_sparse.diagonal(), False)
def test_nn_filter_avg(): srand() X = np.random.randn(10, 100) # Build a recurrence matrix, just for testing purposes rec = librosa.segment.recurrence_matrix(X, mode='affinity') X_filtered = librosa.decompose.nn_filter(X, rec=rec, aggregate=np.average) # Normalize the recurrence matrix so dotting computes an average rec = librosa.util.normalize(rec, axis=1, norm=1) assert np.allclose(X_filtered, X.dot(rec.T))
def test_cross_similarity(n, k, metric): srand() # Make a data matrix data_ref = np.random.randn(3, n) data = np.random.randn(3, n + 7) D = librosa.segment.cross_similarity(data, data_ref, k=k, metric=metric) assert D.shape == (data_ref.shape[1], data.shape[1]) if k is not None: real_k = min(k, n) assert not np.any(D.sum(axis=0) != real_k)
def test_nn_filter_mean(): srand() X = np.random.randn(10, 100) # Build a recurrence matrix, just for testing purposes rec = librosa.segment.recurrence_matrix(X) X_filtered = librosa.decompose.nn_filter(X) # Normalize the recurrence matrix so dotting computes an average rec = librosa.util.normalize(rec.astype(np.float), axis=1, norm=1) assert np.allclose(X_filtered, X.dot(rec.T))
def test_decompose_multi(): srand() X = np.random.random((2, 20, 100)) # Fit with multichannel data components, activations = librosa.decompose.decompose(X, n_components=20, random_state=0) # Reshape the data Xflat = np.vstack([X[0], X[1]]) c_flat, a_flat = librosa.decompose.decompose(Xflat, n_components=20, random_state=0) assert np.allclose(c_flat[:X.shape[1]], components[0]) assert np.allclose(c_flat[X.shape[1]:], components[1]) assert np.allclose(activations, a_flat)
def test_recurrence_distance(self): srand() data = np.random.randn(3, 100) distance = squareform(pdist(data.T, metric='sqeuclidean')) rec = librosa.segment.recurrence_matrix(data, mode='distance', metric='sqeuclidean', sparse=True, self=self) i, j, vals = scipy.sparse.find(rec) assert np.allclose(vals, distance[i, j]) assert np.allclose(rec.diagonal(), 0.0)
def test_cross_similarity_distance(): srand() data_ref = np.random.randn(3, 50) data = np.random.randn(3, 70) distance = cdist(data.T, data_ref.T, metric='sqeuclidean').T rec = librosa.segment.cross_similarity(data, data_ref, mode='distance', metric='sqeuclidean', sparse=True) i, j, vals = scipy.sparse.find(rec) assert np.allclose(vals, distance[i, j])
def test_nn_filter_avg(): srand() X = np.random.randn(10, 100) # Build a recurrence matrix, just for testing purposes rec = librosa.segment.recurrence_matrix(X, mode="affinity") X_filtered = librosa.decompose.nn_filter(X, rec=rec, aggregate=np.average) # Normalize the recurrence matrix so dotting computes an average rec = librosa.util.normalize(rec, axis=0, norm=1) assert np.allclose(X_filtered, X.dot(rec))
def test_nn_filter_mean(): srand() X = np.random.randn(10, 100) # Build a recurrence matrix, just for testing purposes rec = librosa.segment.recurrence_matrix(X) X_filtered = librosa.decompose.nn_filter(X) # Normalize the recurrence matrix so dotting computes an average rec = librosa.util.normalize(rec.astype(np.float), axis=0, norm=1) assert np.allclose(X_filtered, X.dot(rec))
def test_annotation(): def __test(times, annotations, sep): _, tfname = tempfile.mkstemp() os.close(_) # Dump to disk librosa.output.annotation(tfname, times, annotations=annotations, delimiter=sep) # Load it back kwargs = dict() if six.PY3: kwargs['newline'] = '\n' with open(tfname, 'r', **kwargs) as fdesc: for i, line in enumerate(fdesc): row = line.strip().split(sep) assert np.allclose( [float(row[0]), float(row[1])], times[i], atol=1e-3, rtol=1e-3), (row, times) if annotations is not None: assert row[2] == annotations[i] # Remove the file os.unlink(tfname) __test_fail = pytest.mark.xfail(__test, raises=librosa.ParameterError) srand() # Make times and durations strictly non-negative times = np.random.randn(20, 2)**2 times = np.cumsum(times, axis=1) for annotations in [ None, ['abcde'[q] for q in np.random.randint(0, 5, size=len(times))], list('abcde') ]: for sep in [',', '\t', ' ']: if annotations is not None and len(annotations) != len(times): yield __test_fail, times, annotations, sep else: yield __test, times, annotations, sep
def test_nnls_vector(dtype_A, dtype_B): srand() # Make a random basis A = np.random.randn(5, 7).astype(dtype_A) # Make a random latent vector x = np.random.randn(A.shape[1])**2 B = A.dot(x).astype(dtype_B) x_rec = librosa.util.nnls(A, B) assert np.all(x_rec >= 0) assert np.sqrt(np.mean((B - A.dot(x_rec))**2)) <= 1e-6
def test_viterbi_binary_bad_obs(): @raises(librosa.ParameterError) def __bad_obs(x, trans): librosa.sequence.viterbi_binary(x, trans) srand() trans = np.ones((2, 2), dtype=float) / 2. # x is not positive x = -np.ones((3, 5), dtype=float) yield __bad_obs, x, trans # x is too big x = 2 * np.ones((3, 5), dtype=float) yield __bad_obs, x, trans
def test_lag_to_recurrence_sparse(axis, pad): srand() data = np.random.randn(3, 10) rec = librosa.segment.recurrence_matrix(data, sparse=True) lag = librosa.segment.recurrence_to_lag(rec, pad=pad, axis=axis) lag_dense = lag.toarray() rec_sparse = librosa.segment.lag_to_recurrence(lag, axis=axis) rec_dense = librosa.segment.lag_to_recurrence(lag_dense, axis=axis) assert scipy.sparse.issparse(rec_sparse) assert rec_sparse.format == lag.format assert rec_sparse.dtype == lag.dtype assert np.allclose(rec_sparse.toarray(), rec_dense)
def test_dtw_multi(): srand() X = np.random.randn(2, 5, 10) Y = np.random.randn(2, 5, 20) D, wp, steps = librosa.sequence.dtw(X=X, Y=Y, backtrack=True, return_steps=True) # Should give identical results to calling with concatenated inputs Xf = np.concatenate([X[0], X[1]], axis=0) Yf = np.concatenate([Y[0], Y[1]], axis=0) Df, wpf, stepsf = librosa.sequence.dtw(X=Xf, Y=Yf, backtrack=True, return_steps=True) assert np.allclose(D, Df) assert np.allclose(wp, wpf) assert np.allclose(steps, stepsf)
def test_viterbi_binary_bad_obs(): @pytest.mark.xfail(raises=librosa.ParameterError) def __bad_obs(x, trans): librosa.sequence.viterbi_binary(x, trans) srand() trans = np.ones((2, 2), dtype=float) / 2. # x is not positive x = -np.ones((3, 5), dtype=float) yield __bad_obs, x, trans # x is too big x = 2 * np.ones((3, 5), dtype=float) yield __bad_obs, x, trans
def test_nnls_multiblock(dtype_A, dtype_B, x_size): srand() # Make a random basis A = np.random.randn(7, 1025).astype(dtype_A) # Make a random latent matrix # when x_size is 3, B is 7x3 (smaller than A) x = np.random.randn(A.shape[1], x_size)**2 B = A.dot(x).astype(dtype_B) x_rec = librosa.util.nnls(A, B) assert np.all(x_rec >= 0) assert np.sqrt(np.mean((B - A.dot(x_rec))**2)) <= 2e-4
def test_decompose_fit(): srand() D = sklearn.decomposition.NMF(random_state=0) X = np.array([[1, 2, 3, 4, 5, 6], [1, 1, 1.2, 1, 0.8, 1]]) # Do a first fit (W, H) = librosa.decompose.decompose(X, transformer=D, fit=True) # Make random data and decompose with the same basis X = np.random.randn(*X.shape)**2 (W2, H2) = librosa.decompose.decompose(X, transformer=D, fit=False) # Make sure the basis hasn't changed assert np.allclose(W, W2)
def test_poly_features_synthetic(): srand() sr = 22050 n_fft = 2048 def __test(S, coeffs, freq): order = coeffs.shape[0] - 1 p = librosa.feature.poly_features(S=S, sr=sr, n_fft=n_fft, order=order, freq=freq) for i in range(S.shape[-1]): assert np.allclose(coeffs, p[::-1, i].squeeze()) def __make_data(coeffs, freq): S = np.zeros_like(freq) for i, c in enumerate(coeffs): S = S + c * freq**i S = S.reshape((freq.shape[0], -1)) return S for order in range(1, 3): freq = librosa.fft_frequencies(sr=sr, n_fft=n_fft) coeffs = np.atleast_1d(np.arange(1, 1 + order)) # First test: vanilla S = __make_data(coeffs, freq) yield __test, S, coeffs, None # And with explicit frequencies yield __test, S, coeffs, freq # And with alternate frequencies freq = freq**2.0 S = __make_data(coeffs, freq) yield __test, S, coeffs, freq # And multi-dimensional freq = np.cumsum(np.abs(np.random.randn(1 + n_fft // 2, 2)), axis=0) S = __make_data(coeffs, freq) yield __test, S, coeffs, freq
def test_annotation(): def __test(times, annotations, sep): _, tfname = tempfile.mkstemp() # Dump to disk librosa.output.annotation(tfname, times, annotations=annotations, delimiter=sep) # Load it back with open(tfname, 'r') as fdesc: lines = [line for line in fdesc] # Remove the file os.unlink(tfname) for i, line in enumerate(lines): if annotations is None: t_in1, t_in2 = line.strip().split(sep, 2) else: t_in1, t_in2, ann_in = line.strip().split(sep, 3) t_in1 = float(t_in1) t_in2 = float(t_in2) assert np.allclose(times[i], [t_in1, t_in2], atol=1e-3, rtol=1e-3) if annotations is not None: eq_(str(annotations[i]), ann_in) __test_fail = raises(librosa.ParameterError)(__test) srand() times = np.random.randn(20, 2) for annotations in [ None, ['abcde'[q] for q in np.random.randint(0, 5, size=len(times))], list('abcde') ]: for sep in [',', '\t', ' ']: if annotations is not None and len(annotations) != len(times): yield __test_fail, times, annotations, sep else: yield __test, times, annotations, sep
def __test(n, pad): srand() data = np.random.randn(17, n) rec = librosa.segment.recurrence_matrix(data) lag = librosa.segment.recurrence_to_lag(rec, pad=pad, axis=-1) lag2 = librosa.segment.recurrence_to_lag(rec.T, pad=pad, axis=0).T assert np.allclose(lag, lag2) x = Ellipsis if pad: x = slice(n) for i in range(n): assert np.allclose(rec[:, i], np.roll(lag[:, i], i)[x])
def test_axis_sort(): srand() def __test_pass(data, axis, index, value): if index: Xsorted, idx = librosa.util.axis_sort(data, axis=axis, index=index, value=value) cmp_slice = [slice(None)] * X.ndim cmp_slice[axis] = idx assert np.allclose(X[cmp_slice], Xsorted) else: Xsorted = librosa.util.axis_sort(data, axis=axis, index=index, value=value) compare_axis = np.mod(1 - axis, 2) if value is None: value = np.argmax sort_values = value(Xsorted, axis=compare_axis) assert np.allclose(sort_values, np.sort(sort_values)) @raises(librosa.ParameterError) def __test_fail(data, axis, index, value): librosa.util.axis_sort(data, axis=axis, index=index, value=value) for ndim in [1, 2, 3]: X = np.random.randn(*([10] * ndim)) for axis in [0, 1, -1]: for index in [False, True]: for value in [None, np.min, np.mean, np.max]: if ndim == 2: yield __test_pass, X, axis, index, value else: yield __test_fail, X, axis, index, value
def test_dtw_subseq(): srand() # query is a linear ramp X = np.linspace(0, 1, 100) # database is query surrounded by noise noise_len = 200 noise = np.random.rand(noise_len) Y = np.concatenate((noise, noise, X, noise)) _, mut_wp = librosa.sequence.dtw(X, Y, subseq=True) # estimated sequence has to match original sequence # note the +1 due to python indexing mut_X = Y[mut_wp[-1][1]:mut_wp[0][1] + 1] assert np.array_equal(X, mut_X)
def test_viterbi_bad_obs(): @pytest.mark.xfail(raises=librosa.ParameterError) def __bad_obs(trans, x): librosa.sequence.viterbi(x, trans) srand() x = np.random.random(size=(3, 5)) trans = np.ones((3, 3), dtype=float) / 3. # x has values > 1 x[1, 1] = 2 yield __bad_obs, trans, x # x has values < 0 x[1, 1] = -0.5 yield __bad_obs, trans, x
def test_onset_strength_multi_ref(): srand() # Make a random positive spectrum S = 1 + np.abs(np.random.randn(1025, 10)) # Test with a null reference null_ref = np.zeros_like(S) onsets = librosa.onset.onset_strength_multi(S=S, ref=null_ref, aggregate=False, center=False) # since the reference is zero everywhere, S - ref = S # past the setup phase (first frame) assert np.allclose(onsets[:, 1:], S[:, 1:])
def test_recurrence_matrix(n, k, width, sym, metric, self): srand() # Make a data matrix data = np.random.randn(3, n) D = librosa.segment.recurrence_matrix(data, k=k, width=width, sym=sym, axis=-1, metric=metric, self=self) # First test for symmetry if sym: assert np.allclose(D, D.T) # Test for target-axis invariance D_trans = librosa.segment.recurrence_matrix(data.T, k=k, width=width, sym=sym, axis=0, metric=metric, self=self) assert np.allclose(D, D_trans) # If not symmetric, test for correct number of links if not sym and k is not None: real_k = min(k, n - width) if self: real_k += 1 assert not np.any(D.sum(axis=0) != real_k) if self: assert np.allclose(np.diag(D), True) # Make sure the +- width diagonal is hollow # It's easier to test if zeroing out the triangles leaves nothing idx = np.tril_indices(n, k=width) D[idx] = False D.T[idx] = False assert not np.any(D)
def test_times_csv(): def __test(times, annotations, sep): _, tfname = tempfile.mkstemp() os.close(_) # Dump to disk librosa.output.times_csv(tfname, times, annotations=annotations, delimiter=sep) kwargs = dict() if six.PY3: kwargs['newline'] = '\n' # Load it back with open(tfname, 'r', **kwargs) as fdesc: for i, line in enumerate(fdesc): row = line.strip().split(sep) assert np.allclose(float(row[0]), times[i], atol=1e-3, rtol=1e-3), (row, times) if annotations is not None: assert row[1] == annotations[i] # Remove the file os.unlink(tfname) __test_fail = raises(librosa.ParameterError)(__test) srand() for times in [[], np.linspace(0, 10, 20)]: for annotations in [ None, ['abcde'[q] for q in np.random.randint(0, 5, size=len(times))], list('abcde') ]: for sep in [',', '\t', ' ']: if annotations is not None and len(annotations) != len(times): yield __test_fail, times, annotations, sep else: yield __test, times, annotations, sep
def __test(power, split_zeros): srand() X = np.abs(np.random.randn(10, 10)) X_ref = np.abs(np.random.randn(10, 10)) # Zero out some rows X[3, :] = 0 X_ref[3, :] = 0 M = librosa.util.softmask(X, X_ref, power=power, split_zeros=split_zeros) assert np.all(0 <= M) and np.all(M <= 1) if split_zeros and np.isfinite(power): assert np.allclose(M[3, :], 0.5) else: assert not np.any(M[3, :]), M[3]
def test_nn_filter_mean_rec(): srand() X = np.random.randn(10, 100) # Build a recurrence matrix, just for testing purposes rec = librosa.segment.recurrence_matrix(X) # Knock out the first three rows of links rec[:, :3] = False X_filtered = librosa.decompose.nn_filter(X, rec=rec) for i in range(3): assert np.allclose(X_filtered[:, i], X[:, i]) # Normalize the recurrence matrix rec = librosa.util.normalize(rec.astype(np.float), axis=0, norm=1) assert np.allclose(X_filtered[:, 3:], (X.dot(rec))[:, 3:])