Skip to content

Instantly share code, notes, and snippets.

@bmcfee
Last active August 29, 2015 13:56
Show Gist options
  • Save bmcfee/9119470 to your computer and use it in GitHub Desktop.
Save bmcfee/9119470 to your computer and use it in GitHub Desktop.
Propagate time-range annotations (chords) down to a list of reference times (beats)
def beats_to_chords(beat_times, chord_times, chord_labels):
'''Propagate lab-style annotations to a list of beat timings.
:parameters:
- beat_times : ndarray, shape=(m, 2)
The time range for beat intervals.
The `i`th beat spans time `beat_times[i, 0]` to `beat_times[i, 1]`.
`beat_times[0, 0]` should be 0, `beat_times[-1, 1]` should be the track duration.
- chord_times : ndarray, shape=(n, 2)
The time range for the `i`th annotation is `chord_times[i,0]` to `chord_times[i, 1]`.
`chord_times[0, 0]` should be 0, `chord_times[-1, 1]` should be the track duration.
- chord_labels : list of str, shape=(n,)
List of annotation strings associated with `chord_times`
:returns:
- beat_labels : list of str, shape=(len(beat_times)-1,)
Chord annotations at the beat level.
'''
# The overlap score of a beat with a segment is defined as
# max(0, min(beat_end, segment_end) - max(beat_start, segment_start))
ends = np.minimum.outer(beat_times[:, 1], chord_times[:, 1])
starts = np.maximum.outer(beat_times[:, 0], chord_times[:, 0])
score = np.maximum(0, ends - starts)
return [chord_labels[c] for c in np.argmax(score, axis=1)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment