Skip to content

Commit

Permalink
Speed up resample_melody_series (#218)
Browse files Browse the repository at this point in the history
  • Loading branch information
rabitt authored and craffel committed Aug 27, 2016
1 parent 2675ab6 commit 0d9cdc7
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
3 changes: 2 additions & 1 deletion docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ v0.4
- `#208`_: refactored file/buffer loading
- `#210`_: added `io.load_tempo`
- `#212`_: added frame-wise blind-source separation evaluation
- `#218`_: speed up `melody.resample_melody_series` when times are equivalent

.. _#189: https://github.com/craffel/mir_eval/issues/189
.. _#195: https://github.com/craffel/mir_eval/issues/195
Expand Down Expand Up @@ -40,7 +41,7 @@ v0.2
- `#103`_: incomplete files passed to `melody.evaluate` should warn
- `#109`_: `STRICT_BASS_INTERVALS` is now an argument to `chord.encode`
- `#122`_: improved handling of corner cases in beat tracking
- `#136`_: improved test coverage
- `#136`_: improved test coverage
- `#138`_: PEP8 compliance
- `#139`_: converted documentation to numpydoc style
- `#147`_: fixed a rounding error in segment intervals
Expand Down
9 changes: 8 additions & 1 deletion mir_eval/melody.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,12 @@ def constant_hop_timebase(hop, end_time):

def resample_melody_series(times, frequencies, voicing,
times_new, kind='linear'):
"""Resamples frequency and voicing time series to a new timescale. Maintains
"""Resamples frequency and voicing time series to a new timescale. Maintains
any zero ("unvoiced") values in frequencies.
If ``times`` and ``times_new`` are equivalent, no resampling will be
performed.
Parameters
----------
times : np.ndarray
Expand All @@ -214,6 +217,10 @@ def resample_melody_series(times, frequencies, voicing,
Boolean voicing array resampled to new timebase
"""
# If the timebases are already the same, no need to interpolate
if times.shape == times_new.shape and np.allclose(times, times_new):
return frequencies, voicing.astype(np.bool)

# Warn when the delta between the original times is not constant,
# unless times[0] == 0. and frequencies[0] == frequencies[1] (see logic at
# the beginning of to_cent_voicing)
Expand Down
15 changes: 15 additions & 0 deletions tests/test_melody.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ def test_resample_melody_series():
assert np.allclose(res_voicing, expected_voicing)


def test_resample_melody_series_same_times():
# Check the case where the time bases are identical
times = np.array([0.0, 0.1, 0.2, 0.3])
times_new = np.array([0.0, 0.1, 0.2, 0.3])
cents = np.array([2., 0., -1., 1.])
voicing = np.array([0, 0, 1, 1])
expected_cents = np.array([2., 0., -1., 1.])
expected_voicing = np.array([False, False, True, True])
(res_cents,
res_voicing) = mir_eval.melody.resample_melody_series(times, cents,
voicing, times_new)
assert np.allclose(res_cents, expected_cents)
assert np.allclose(res_voicing, expected_voicing)


def test_to_cent_voicing():
# We'll just test a few values from one of the test annotations
ref_file = sorted(glob.glob(REF_GLOB))[0]
Expand Down

0 comments on commit 0d9cdc7

Please sign in to comment.