def test_can_slice_time_series_with_open_ended_time_slice(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) sl = TimeSlice(None, start=Seconds(2)) ts2 = ts[sl] self.assertEqual(8, len(ts2))
def test_can_mix_time_slice_and_integer_indices(self): arr = np.ones((10, 5)) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq), IdentityDimension()]) sl = TimeSlice(duration=Seconds(5), start=Seconds(5)) ts2 = ts[sl, 2:] self.assertEqual((5, 3), ts2.shape)
def test_concat_with_differing_durations(self): td1 = TimeDimension(Seconds(1), Seconds(2)) ts1 = ArrayWithUnits(np.ones((10, 3)), [td1, IdentityDimension()]) td2 = TimeDimension(Seconds(1), Seconds(3)) ts2 = ArrayWithUnits(np.ones((13, 3)), [td2, IdentityDimension()]) self.assertRaises(ValueError, lambda: ArrayWithUnits.concat([ts1, ts2]))
def test_time_slice_should_return_audio_samples(self): silence = AudioSamples.silence(SR11025(), Seconds(10)) ts = TimeSlice(duration=Seconds(1)) sliced = silence[ts] self.assertIsInstance(sliced, AudioSamples) self.assertEqual(int(SR11025()), len(sliced)) self.assertEqual(SR11025(), sliced.samplerate)
def test_concat_along_first_axis(self): td1 = TimeDimension(Seconds(1), Seconds(2)) ts1 = ArrayWithUnits(np.ones((10, 3)), [td1, IdentityDimension()]) td2 = TimeDimension(Seconds(1), Seconds(2)) ts2 = ArrayWithUnits(np.ones((13, 3)), [td2, IdentityDimension()]) result = ArrayWithUnits.concat([ts1, ts2]) self.assertEqual((23, 3), result.shape)
def test_sum_along_second_axis(self): td = TimeDimension(Seconds(1), Seconds(2)) ts = ArrayWithUnits(np.ones((10, 3)), [td, IdentityDimension()]) result = ts.sum(axis=1) self.assertIsInstance(result, ArrayWithUnits) self.assertEqual((10, ), result.shape) self.assertEqual(1, len(result.dimensions)) self.assertIsInstance(result.dimensions[0], TimeDimension)
def test_can_produce_time_slice_iterable_from_timestamps(self): slices = TimeSlice.slices([Seconds(1), Milliseconds(1), Seconds(2)]) self.assertEqual(2, len(slices)) self.assertEqual( TimeSlice(start=Milliseconds(1), duration=Milliseconds(999)), slices[0]) self.assertEqual(TimeSlice(start=Seconds(1), duration=Seconds(1)), slices[1])
def test_get_empty_time_series_when_using_out_of_range_time_slice(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) sl = TimeSlice(Seconds(2), start=Seconds(11)) ts2 = ts[sl] self.assertEqual(0, ts2.size) self.assertIsInstance(ts2, ArrayWithUnits)
def test_concat_along_second_axis(self): td1 = TimeDimension(Seconds(1), Seconds(2)) ts1 = ArrayWithUnits(np.ones((10, 3)), [td1, IdentityDimension()]) td2 = TimeDimension(Seconds(1), Seconds(2)) ts2 = ArrayWithUnits(np.ones((10, 5)), [td2, IdentityDimension()]) result = ArrayWithUnits.concat([ts1, ts2], axis=1) self.assertEqual((10, 8), result.shape) self.assertIsInstance(result.dimensions[0], TimeDimension) self.assertIsInstance(result.dimensions[1], IdentityDimension)
def test_frequency_and_duration_differ3(self): arr = np.arange(10) freq = Seconds(1) duration = Seconds(3) ts = ArrayWithUnits(arr, [TimeDimension(freq, duration)]) sl = TimeSlice(Seconds(2), start=Seconds(6)) ts2 = ts[sl] self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(4, ts2.size) self.assertTrue(np.all(np.arange(4, 8) == ts2))
def test_concat_with_differing_freqs(self): ts = ArrayWithUnits(np.ones( (10, 3)), [TimeDimension(Seconds(2), Seconds(2)), IdentityDimension()]) ts2 = ArrayWithUnits(np.ones( (13, 3)), [TimeDimension(Seconds(1), Seconds(2)), IdentityDimension()]) self.assertRaises(ValueError, lambda: ArrayWithUnits.concat([ts, ts2]))
def test_duration_less_than_frequency(self): arr = np.arange(10) freq = Seconds(1) duration = Milliseconds(500) ts = ArrayWithUnits(arr, [TimeDimension(freq, duration)]) sl = TimeSlice(Seconds(3), start=Milliseconds(1250)) ts2 = ts[sl] self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(4, ts2.size) self.assertTrue(np.all(np.arange(1, 5) == ts2))
def test_frequency_less_than_one_freq_and_duration_differ(self): arr = np.arange(10) freq = Milliseconds(500) duration = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq, duration)]) sl = TimeSlice(Seconds(3), start=Milliseconds(250)) ts2 = ts[sl] self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(7, ts2.size) self.assertTrue(np.all(np.arange(0, 7) == ts2))
def test_concatenation_with_matching_freqs_and_duration_results_in_crts( self): ts = ArrayWithUnits(np.ones( (10, 3)), [TimeDimension(Seconds(1), Seconds(2)), IdentityDimension()]) ts2 = ArrayWithUnits(np.ones( (13, 3)), [TimeDimension(Seconds(1), Seconds(2)), IdentityDimension()]) result = ts.concatenate(ts2) self.assertIsInstance(result, ArrayWithUnits) self.assertEqual((23, 3), result.shape)
def test_can_slice_constant_rate_time_series_with_integer_indices(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) ts2 = ts[:5] self.assertEqual(5, len(ts2)) self.assertIsInstance(ts2, ArrayWithUnits)
def test_can_get_entire_time_series_with_empty_time_slice(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) sl = TimeSlice() ts2 = ts[sl] self.assertEqual(10, len(ts2))
def test_can_add_constant_factor_to_time_series(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) ts2 = ts + 10 self.assertTrue(np.all(np.arange(10, 20) == ts2)) self.assertIsInstance(ts2, ArrayWithUnits)
def test_sliding_window_dimensions(self): samplerate = SR11025() samples = AudioSamples.silence(SR11025(), Seconds(10)) window_sr = SampleRate( duration=samplerate.frequency * 512, frequency=samplerate.frequency * (512 - 25)) windowed = samples.sliding_window(window_sr) self.assertEqual(window_sr, windowed.dimensions[0].samplerate)
def test_stereo(self): silence = AudioSamples.silence(SR11025(), Seconds(10)) self.assertEqual(1, silence.channels) stereo = silence.stereo self.assertEqual(2, stereo.channels) self.assertEqual((len(silence), 2), stereo.shape) np.testing.assert_allclose(silence, stereo[:, 0]) np.testing.assert_allclose(silence, stereo[:, 1])
def test_can_get_entire_time_series_with_empty_slice(self): arr = np.arange(10) freq = Seconds(1) duration = Milliseconds(500) ts = ArrayWithUnits(arr, [TimeDimension(freq, duration)]) ts2 = ts[:] self.assertIsInstance(ts2, ArrayWithUnits) self.assertTrue(np.all(np.arange(10) == ts2))
def test_encode_large_ogg(self): sr = SR11025() synth = SilenceSynthesizer(sr) samples = synth.synthesize(Seconds(190)) raw = samples.encode(fmt='OGG', subtype='VORBIS') # prior to this test, the line above caused a segfault, so the assertion # below is fairly worthless, and mostly a formality self.assertIsNotNone(raw)
def test_resampled(self): original_frequency = Milliseconds(500) original_duration = Seconds(1) ratio = 0.02 orig_sr = SampleRate(original_frequency, original_duration) new_sr = orig_sr.resample(ratio) self.assertEqual(Milliseconds(10), new_sr.frequency) self.assertEqual(Milliseconds(20), new_sr.duration)
def test_can_sum_2d_timeseries(self): arr = np.zeros((10, 3)) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq), IdentityDimension()]) ts2 = ts.sum(axis=1) self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(1, len(ts2.dimensions)) self.assertEqual(freq, ts2.dimensions[0].frequency) self.assertEqual(freq, ts2.dimensions[0].duration)
def test_time_slice_spanning_multiple_samples_returns_all_samples(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) sl = TimeSlice(Milliseconds(2000), start=Milliseconds(1500)) ts2 = ts[sl] self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(3, ts2.size) self.assertTrue(np.all(np.arange(1, 4) == ts2))
def test_time_slice_spanning_less_than_one_sample_returns_one_sample(self): arr = np.arange(10) freq = Seconds(1) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) sl = TimeSlice(Milliseconds(100), start=Milliseconds(1500)) ts2 = ts[sl] self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(1, ts2.size) self.assertEqual(1, ts2[0])
def test_frequency_less_than_one(self): arr = np.arange(10) freq = Milliseconds(500) ts = ArrayWithUnits(arr, [TimeDimension(freq)]) sl = TimeSlice(Seconds(2), start=Milliseconds(600)) ts2 = ts[sl] self.assertIsInstance(ts2, ArrayWithUnits) self.assertEqual(5, ts2.size) self.assertTrue(np.all(np.arange(1, 6) == ts2))
def integer_based_slice(self, ts): """ Transform a :class:`TimeSlice` into integer indices that numpy can work with Args: ts (slice, TimeSlice): the time slice to translate into integer indices """ if isinstance(ts, slice): try: start = Seconds(0) if ts.start is None else ts.start if start < Seconds(0): start = self.end + start stop = self.end if ts.stop is None else ts.stop if stop < Seconds(0): stop = self.end + stop duration = stop - start ts = TimeSlice(start=start, duration=duration) except (ValueError, TypeError): pass if not isinstance(ts, TimeSlice): return ts diff = self.duration - self.frequency start_index = \ max(0, np.floor((ts.start - diff) / self.frequency)) end = self.end if ts.duration is None else ts.end # KLUDGE: This is basically arbitrary, but the motivation is that we'd # like to differentiate between cases where the slice # actually/intentionally overlaps a particular sample, and cases where # the slice overlaps the sample by a tiny amount, due to rounding or # lack of precision (e.g. Seconds(1) / SR44100().frequency). ratio = np.round(end / self.frequency, 2) stop_index = np.ceil(ratio) return slice(int(start_index), int(stop_index))
def test_sliding_window(self): samples = AudioSamples.silence(SR11025(), Seconds(30)) sr = samples.samplerate * Stride(frequency=16, duration=512) windowed = samples.sliding_window(sr) self.assertEqual((512,), windowed.shape[1:]) long_sr = SampleRate( frequency=sr.frequency * 2, duration=sr.frequency * 32) frequency = TimeSlice(duration=long_sr.frequency) duration = TimeSlice(duration=long_sr.duration) _, long_windowed = windowed.sliding_window_with_leftovers( windowsize=duration, stepsize=frequency, dopad=True) self.assertEqual((32, 512), long_windowed.shape[1:]) self.assertEqual(3, long_windowed.ndim)
def test_can_unpack_samplerate(self): sr = SampleRate(Seconds(1), Seconds(2)) frequency, duration = sr self.assertEqual(Seconds(1), frequency) self.assertEqual(Seconds(2), duration)
def test_raises_value_error_for_negative_duration(self): self.assertRaises(ValueError, lambda: SampleRate(Seconds(1), Seconds(-1)))