diff --git a/partitura/performance.py b/partitura/performance.py index ef434120..9bfa6ef4 100644 --- a/partitura/performance.py +++ b/partitura/performance.py @@ -178,7 +178,8 @@ def note_array(self, *args, **kwargs) -> np.ndarray: duration_sec = offset - note_on_sec duration_tick = ( n.get( - "note_off_tick", + seconds_to_midi_ticks( + n["sound_off"], mpq=self.mpq, ppq=self.ppq), seconds_to_midi_ticks(n["note_off"], mpq=self.mpq, ppq=self.ppq), ) - note_on_tick @@ -281,7 +282,6 @@ def adjust_offsets_w_sustain( pedal = pedal[np.argsort(pedal[:, 0]), :] # reduce the pedal info to just the times where there is a change in pedal state - pedal = np.vstack( ( (min(pedal[0, 0] - 1, first_off - 1), 0), @@ -299,7 +299,23 @@ def adjust_offsets_w_sustain( next_pedal_time = pedal[last_pedal_change_before_off + 1, 0] offs[pedal_down_at_off] = next_pedal_time[pedal_down_at_off] + + # adjust offset times of notes that have a reonset while the sustain pedal is on + pitches = np.array([n["midi_pitch"] for n in notes]) + note_ons = np.array([n["note_on"] for n in notes]) + + for pitch in np.unique(pitches): + pitch_indices = np.where(pitches == pitch)[0] + + sorted_indices = pitch_indices[np.argsort(note_ons[pitch_indices])] + sorted_note_ons = note_ons[sorted_indices] + sorted_sound_offs = offs[sorted_indices] + + adjusted_sound_offs = np.minimum( + sorted_sound_offs[:-1], sorted_note_ons[1:]) + offs[sorted_indices[:-1]] = adjusted_sound_offs + for offset, note in zip(offs, notes): note["sound_off"] = offset diff --git a/tests/test_performance_features.py b/tests/test_performance_features.py index e0c4723a..566ba105 100644 --- a/tests/test_performance_features.py +++ b/tests/test_performance_features.py @@ -11,32 +11,36 @@ import os - class TestPerformanceFeatures(unittest.TestCase): def test_performance_features(self): - fields = ['id','pedal_feature.onset_value','pedal_feature.offset_value','pedal_feature.to_prev_release', - 'pedal_feature.to_next_release','onset','duration', 'pitch', 'p_onset', 'p_duration','velocity', 'beat_period'] - True_array = np.array([('n1', 0.23374297, 89.74999 , 62.000057, 0., 0.16015087, -0.5, 0.5 , 59, 4.9925 , 0.8775 , 44, 1.4700003), - ('n4', 0.03011051, 114.25004 , 61.000244, 0., 0.4027142 , 0. , 1. , 40, 5.7025 , 2.4375 , 22, 2.8474998), - ('n3', 2.527984 , 87.500046, 61.000244, 0., 0.4027142 , 0. , 0.25, 56, 5.77625, 2.36375, 26, 2.8474998)], - dtype=[('id', '