Trim Silence
Mannerow opened this issue · 3 comments
Hello,
I'm just wondering how you would suggest trimming silence on MIDI files? I have lots of data where I would like to remove silence from the start and end.
The only method I've found online involves converting to a piano_roll, however, there doesn't seem to be a function to convert back from a piano roll to PrettyMIDI.
I can see that the PrettyMIDI files have functions for getting the starting/ending time (estimate_beat_start, get_end_time). Is there any way to use these methods and change the MIDI file so that it only contains data in between the starting/end time?
Thanks
You can use get_end_time
to get the time of the final event: https://github.com/craffel/pretty-midi/blob/main/pretty_midi/pretty_midi.py#L441 and make an almost-identical function (doing a min
instead of a max
) to get the start time. Then, you can do adjust_times([0, end_time - start_time], [start_time, end_time])
.
Here's how I ended up trimming the starting silence (just the reverse of what you said):
#Trim starting silence.
endTime = pm.get_end_time()
startTime = get_start_time(pm)
pm.adjust_times([startTime,endTime],[0,endTime-startTime])
Now I'm working on removing any silent bars, and I'm finding it a bit tricky. It seems like adjust_times isn't the best choice for this, since I actually want to cut these silences out completely. So, I'm trying to do it by iterating through each downbeat, converting this into an index into the piano_roll, and then deleting every section of the piano_roll that doesn't have any notes.
Here is my code:
#Trim bars that are silent
downbeats = pm.get_downbeats()[1:]
pr = pm.get_piano_roll().T
newPR = np.copy(pr)
prev = 0
for d in downbeats:
current = (int)(round(d,2)*100)
if (current < len(pr)):
prSection = pr[prev:current]
summed = np.sum(prSection, axis=0)
all_zero = not np.any(summed)
if all_zero:
# pdb.set_trace()
newPR = np.delete(newPR,slice(prev,current),0)
prev = current
pm = piano_roll_to_pretty_midi(newPR.T)
So far, this isn't working. Does anyone have any suggestions or maybe an easier way to do this?