def test_raises_value_error_when_specified_axis_not_frequency_dim(self): samplerate = SR22050() samples = SineSynthesizer(samplerate) \ .synthesize(Milliseconds(2500), [220, 440, 880]) self.assertRaises( ValueError, lambda: phase_shift(samples, samplerate, Milliseconds(10)))
def test_can_round_trip_3d_constant_rate_time_series_with_frequency_dim( self): dim1 = TimeDimension(Seconds(2), Milliseconds(1000)) dim2 = TimeDimension(Seconds(1), Milliseconds(500)) scale = LinearScale(FrequencyBand(20, 20000), 100) dim3 = FrequencyDimension(scale) raw = np.random.random_sample((5, 2, 100)) ts = ArrayWithUnits(raw, (dim1, dim2, dim3)) decoded = self._roundtrip(ts) self.assertIsInstance(decoded, ArrayWithUnits) self.assertEqual(3, len(decoded.dimensions)) td1 = decoded.dimensions[0] self.assertIsInstance(td1, TimeDimension) self.assertEqual(Seconds(2), td1.frequency) self.assertEqual(Milliseconds(1000), td1.duration) td2 = decoded.dimensions[1] self.assertIsInstance(td2, TimeDimension) self.assertEqual(Seconds(1), td2.frequency) self.assertEqual(Milliseconds(500), td2.duration) fd = decoded.dimensions[2] self.assertIsInstance(fd, FrequencyDimension) self.assertEqual(scale, fd.scale) np.testing.assert_allclose(decoded, raw)
def test_can_phase_shift_1d_signal(self): samplerate = SR22050() samples = SineSynthesizer(samplerate) \ .synthesize(Milliseconds(5000), [220, 440, 880]) coeffs = fft(samples) shifted = phase_shift(coeffs, samplerate, Milliseconds(10)) new_samples = np.fft.irfft(shifted, norm='ortho') self.assertNotEqual(0, self._mean_squared_error(samples, new_samples))
def test_can_round_trip(self): td = TimeDimension(Seconds(1), Milliseconds(500), 100) encoded = self.encoder.encode(td) decoded = self.decoder.decode(encoded) self.assertIsInstance(decoded, TimeDimension) self.assertEqual(Seconds(1), decoded.frequency) self.assertEqual(Milliseconds(500), decoded.duration) self.assertEqual(100, decoded.size)
def test_1d_phase_shift_returns_correct_size(self): samplerate = SR22050() samples = SineSynthesizer(samplerate) \ .synthesize(Milliseconds(5500), [220, 440, 880]) coeffs = fft(samples) shifted = phase_shift(coeffs=coeffs, samplerate=samplerate, time_shift=Milliseconds(5500), frequency_band=FrequencyBand(50, 5000)) self.assertEqual(coeffs.shape, shifted.shape)
def test_can_take_fft_of_2d_stacked_signal(self): samples = SilenceSynthesizer(SR22050()).synthesize(Milliseconds(2500)) windowsize = TimeSlice(duration=Milliseconds(200)) stepsize = TimeSlice(duration=Milliseconds(100)) _, windowed = samples.sliding_window_with_leftovers( windowsize=windowsize, stepsize=stepsize, dopad=True) coeffs = fft(windowed) self.assertIsInstance(coeffs, ArrayWithUnits) self.assertEqual(2, len(coeffs.dimensions)) self.assertEqual(windowed.dimensions[0], coeffs.dimensions[0]) self.assertIsInstance(coeffs.dimensions[1], FrequencyDimension)
def test_can_round_trip_1d_constant_rate_time_series(self): dim = TimeDimension(Seconds(1), Milliseconds(500)) raw = np.arange(10) ts = ArrayWithUnits(raw, (dim, )) decoded = self._roundtrip(ts) self.assertIsInstance(decoded, ArrayWithUnits) self.assertEqual(1, len(decoded.dimensions)) self.assertIsInstance(decoded.dimensions[0], TimeDimension) td = decoded.dimensions[0] self.assertEqual(Seconds(1), td.frequency) self.assertEqual(Milliseconds(500), td.duration) np.testing.assert_allclose(decoded, raw)
def test_can_pad_for_better_frequency_resolution(self): samples = SilenceSynthesizer(SR22050()).synthesize(Milliseconds(2500)) windowsize = TimeSlice(duration=Milliseconds(200)) stepsize = TimeSlice(duration=Milliseconds(100)) _, windowed = samples.sliding_window_with_leftovers( windowsize=windowsize, stepsize=stepsize, dopad=True) coeffs = fft(windowed, padding_samples=1024) self.assertIsInstance(coeffs, ArrayWithUnits) self.assertEqual(2, len(coeffs.dimensions)) self.assertEqual(windowed.dimensions[0], coeffs.dimensions[0]) self.assertIsInstance(coeffs.dimensions[1], FrequencyDimension) expected_size = ((windowed.shape[-1] + 1024) // 2) + 1 self.assertEqual(expected_size, coeffs.shape[-1])
def test_can_phase_shift_2d_signal(self): samplerate = SR22050() samples = SineSynthesizer(samplerate) \ .synthesize(Milliseconds(2500), [220, 440, 880]) windowsize = TimeSlice(duration=Milliseconds(200)) stepsize = TimeSlice(duration=Milliseconds(100)) _, windowed = samples.sliding_window_with_leftovers( windowsize=windowsize, stepsize=stepsize, dopad=True) coeffs = fft(windowed) shifted = phase_shift(coeffs, samplerate, Milliseconds(40)) synth = FFTSynthesizer() new_samples = synth.synthesize(shifted).squeeze() self.assertNotEqual(0, self._mean_squared_error(samples, new_samples))
def test_2d_phase_shift_returns_correct_shape(self): samplerate = SR22050() samples = SineSynthesizer(samplerate) \ .synthesize(Milliseconds(2500), [220, 440, 880]) windowsize = TimeSlice(duration=Milliseconds(200)) stepsize = TimeSlice(duration=Milliseconds(100)) _, windowed = samples.sliding_window_with_leftovers( windowsize=windowsize, stepsize=stepsize, dopad=True) coeffs = fft(windowed) shifted = phase_shift(coeffs=coeffs, samplerate=samplerate, time_shift=Milliseconds(40), frequency_band=FrequencyBand(50, 5000)) self.assertEqual(coeffs.shape, shifted.shape)
def test_can_round_trip_2d_with_identity_dimension(self): raw = np.random.random_sample((10, 10)) dim = TimeDimension(Seconds(1), Milliseconds(500)) arr = ArrayWithUnits(raw, (IdentityDimension(), dim)) decoded = self._roundtrip(arr) self.assertIsInstance(decoded, ArrayWithUnits) self.assertEqual(2, len(decoded.dimensions)) idd = decoded.dimensions[0] self.assertIsInstance(idd, IdentityDimension) td = decoded.dimensions[1] self.assertIsInstance(td, TimeDimension) self.assertEqual(Seconds(1), td.frequency) self.assertEqual(Milliseconds(500), td.duration) np.testing.assert_allclose(decoded, raw)
def test_square_form_no_overlap_add(self): samplerate = SR11025() BaseModel = stft(resample_to=samplerate) windowing_func = OggVorbisWindowingFunc() scale = GeometricScale(20, 5000, 0.1, 25) @simple_in_memory_settings class Document(BaseModel): long_windowed = ArrayWithUnitsFeature( SlidingWindow, wscheme=SampleRate(frequency=Milliseconds(500), duration=Seconds(1)), wfunc=windowing_func, needs=BaseModel.resampled, store=True) dct = ArrayWithUnitsFeature(DCT, scale_always_even=True, needs=long_windowed, store=True) mdct = FrequencyAdaptiveFeature(FrequencyAdaptiveTransform, transform=scipy.fftpack.idct, scale=scale, needs=dct, store=True) synth = TickSynthesizer(SR22050()) samples = synth.synthesize(Seconds(5), Milliseconds(200)) _id = Document.process(meta=samples.encode()) doc = Document(_id) square = doc.mdct.square(30) self.assertEqual(3, square.ndim) self.assertEqual(30, square.shape[1]) self.assertEqual(25, square.shape[2])
def auto_correlogram(x, filter_bank, correlation_window=Milliseconds(30)): n_filters = filter_bank.shape[0] filter_size = filter_bank.shape[1] corr_win_samples = int(correlation_window / x.samplerate.frequency) windowed = sliding_window(x, filter_size, 1, flatten=False) print(windowed.shape) filtered = np.dot(windowed, filter_bank.T) print(filtered.shape) corr = sliding_window(filtered, ws=(corr_win_samples, n_filters), ss=(1, n_filters), flatten=False) print(corr.shape) padded_shape = list(corr.shape) padded_shape[2] = corr_win_samples * 2 padded = np.zeros(padded_shape, dtype=np.float32) padded[:, :, :corr_win_samples, :] = corr print(padded.shape) coeffs = np.fft.fft(padded, axis=2, norm='ortho') correlated = np.fft.ifft(np.abs(coeffs)**2, axis=2, norm='ortho') return np.concatenate([ correlated[:, :, corr_win_samples:, :], correlated[:, :, :corr_win_samples, :], ], axis=2) return correlated
def test_can_access_single_frequency_band(self): td = TimeDimension(duration=Seconds(1), frequency=Milliseconds(500)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.zeros((10, x)) for x in xrange(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) sliced = fa[:, scale[0]] self.assertEqual((10, 1), sliced.shape)
def test_stft_raises_for_invalid_dimensions(self): sr = SR22050() samples = SilenceSynthesizer(sr).synthesize(Milliseconds(6666)) wscheme = sr.windowing_scheme(512, 256) tf = stft(samples, wscheme, HanningWindowingFunc()) self.assertRaises(ValueError, lambda: stft(tf, wscheme, HanningWindowingFunc()))
def test_from_timeslice_closed(self): ts = TimeSlice( start=Picoseconds(int(1e12)) * 2.5, duration=Milliseconds(2000)) self.assertEqual( 'seconds 2.5-4.5/100.0', str(ContentRange.from_timeslice(ts, Seconds(100))))
def test_can_contract_audio_samples(self): sr = SR22050() samples = SilenceSynthesizer(sr).synthesize(Milliseconds(1000)) print('First', samples.shape, samples.dimensions) stretched = time_stretch(samples, 2.0).squeeze() print('Second', stretched.shape, stretched.dimensions) self.assertEqual(len(samples) // 2, len(stretched))
def test_can_roundtrip_frequency_adaptive_transform(self): td = TimeDimension(duration=Seconds(1), frequency=Milliseconds(500)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.zeros((10, x)) for x in range(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) decoded = self._roundtrip(fa, decoder=FrequencyAdaptiveDecoder()) self.assertIsInstance(decoded, FrequencyAdaptive) self.assertEqual(fa.dimensions, decoded.dimensions)
def test_can_round_trip_mixed_dimensions(self): original = [ IdentityDimension(), TimeDimension(Seconds(1), Milliseconds(500)), FrequencyDimension(LinearScale(FrequencyBand(100, 1000), 10)) ] restored = self.roundtrip(original) self.assertSequenceEqual(original, restored)
def test_can_invert_frequency_weighting_for_adaptive_representation(self): td = TimeDimension(duration=Seconds(1), frequency=Milliseconds(500)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.random.random_sample((10, x)) for x in xrange(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) weighting = AWeighting() result = fa * weighting inverted = result / AWeighting() np.testing.assert_allclose(fa, inverted)
def test_preserves_time_dimension(self): sr = SR22050() samples = TickSynthesizer(sr).synthesize(Milliseconds(10000), Milliseconds(1000)) wscheme = sr.windowing_scheme(256, 128) scale = GeometricScale(50, sr.nyquist, 0.4, 32) scale.ensure_overlap_ratio() tf = stft(samples, wscheme, HanningWindowingFunc()) geom = apply_scale(tf, scale, window=HanningWindowingFunc()) # get the loudness envelope of each tf_envelope = np.abs(tf.real).sum(axis=1) geom_envelope = geom.sum(axis=1) tf_zeros = np.where(tf_envelope == 0) geom_zeros = np.where(geom_envelope == 0) np.testing.assert_allclose(tf_zeros, geom_zeros)
def test_has_correct_shape(self): sr = SR22050() samples = SilenceSynthesizer(sr).synthesize(Milliseconds(9999)) wscheme = sr.windowing_scheme(256, 128) scale = GeometricScale(50, sr.nyquist, 0.4, 32) scale.ensure_overlap_ratio() tf = stft(samples, wscheme, HanningWindowingFunc()) geom = apply_scale(tf, scale, window=HanningWindowingFunc()) self.assertEqual(tf.shape[:-1] + (len(scale), ), geom.shape)
def test_can_apply_a_weighting_to_frequency_adaptive_representation(self): td = TimeDimension(duration=Seconds(1), frequency=Milliseconds(500)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.ones((10, x)) for x in xrange(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) weighting = AWeighting() result = fa * weighting self.assertGreater(result[:, scale[-1]].sum(), result[:, scale[0]].sum())
def test_can_invert_weighting_for_explicit_frequency_dimension(self): td = TimeDimension(duration=Seconds(1), frequency=Milliseconds(500)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.ones((10, x)) for x in xrange(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) fa2 = ArrayWithUnits(fa, fa.dimensions) weighting = AWeighting() result = fa2 * weighting inverted = result / AWeighting() np.testing.assert_allclose(fa, inverted)
def test_apply_scale_to_self_is_identity_function(self): samplerate = SR22050() samples = SineSynthesizer(samplerate).synthesize(Milliseconds(8888)) wscheme = samplerate.windowing_scheme(256, 128) tf = stft(samples, wscheme, HanningWindowingFunc()) scale = tf.dimensions[-1].scale transformed = apply_scale(tf, scale, HanningWindowingFunc()) self.assertEqual(tf.shape, transformed.shape) self.assertEqual(tf.dimensions[0], transformed.dimensions[0]) self.assertEqual(tf.dimensions[1], transformed.dimensions[1])
def test_can_apply_weighting_to_explicit_frequency_dimension(self): td = TimeDimension(duration=Seconds(1), frequency=Milliseconds(500)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.ones((10, x)) for x in xrange(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) fa2 = ArrayWithUnits(fa, fa.dimensions) weighting = AWeighting() result = fa2 * weighting self.assertGreater(result[:, scale[-1]].sum(), result[:, scale[0]].sum())
def test_can_stretch_audio_batch(self): sr = SR22050() samples = SilenceSynthesizer(sr).synthesize(Milliseconds(6666)) stacked = ArrayWithUnits( np.zeros((10, ) + samples.shape, dtype=samples.dtype), (IdentityDimension(), ) + samples.dimensions) stacked[:] = samples stretched = time_stretch(stacked, 2.0) self.assertEqual(10, stretched.shape[0]) self.assertEqual(int(len(samples) // 2), stretched.shape[1])
def test_iter_slices_yields_evenly_spaced_time_slices(self): raw = np.random.random_sample((10, 3)) arr = ArrayWithUnits(raw, dimensions=[ TimeDimension(frequency=Milliseconds(500), duration=Seconds(1)), IdentityDimension() ]) crts = ConstantRateTimeSeries(arr) slices = list(crts.iter_slices()) self.assertEqual(10, len(slices)) ts1, d1 = slices[0] self.assertEqual(TimeSlice(start=Seconds(0), duration=Seconds(1)), ts1) np.testing.assert_allclose(raw[0], d1) ts2, d2 = slices[1] self.assertEqual( TimeSlice(start=Milliseconds(500), duration=Seconds(1)), ts2) np.testing.assert_allclose(raw[1], d2)
class Document(rs): long_windowed = ArrayWithUnitsFeature( SlidingWindow, wscheme=SampleRate(Milliseconds(500), Seconds(1)), wfunc=OggVorbisWindowingFunc(), needs=rs.resampled, store=True) long_fft = ArrayWithUnitsFeature(FFT, needs=long_windowed, store=True)
def test_square_form_no_overlap_do_overlap_add(self): td = TimeDimension(duration=Seconds(1), frequency=Seconds(1)) scale = GeometricScale(20, 5000, 0.05, 120) arrs = [np.zeros((10, x)) for x in xrange(1, 121)] fa = FrequencyAdaptive(arrs, td, scale) square = fa.square(50, do_overlap_add=True) self.assertEqual(2, square.ndim) self.assertEqual(500, square.shape[0]) self.assertEqual(120, square.shape[1]) self.assertIsInstance(square, ArrayWithUnits) self.assertIsInstance(square.dimensions[0], TimeDimension) self.assertEqual(Seconds(10), square.dimensions[0].end) self.assertEqual(Milliseconds(20), square.dimensions[0].frequency) self.assertEqual(Milliseconds(20), square.dimensions[0].duration) self.assertIsInstance(square.dimensions[1], FrequencyDimension) self.assertEqual(scale, square.dimensions[1].scale)