mimbres / YourMT3

multi-task and multi-track music transcription for everyone
GNU General Public License v3.0
100 stars 3 forks source link

MIDI end of file duration mismatch with input audio duration #14

Open nateraw opened 4 days ago

nateraw commented 4 days ago

Hi there, this is the issue I was referring to in #13 - reporting anyway even though code isn't here to refer to.

Not sure if this is on purpose or not, but I've noticed there's a mismatch between input audio file duration and the length of the midi data saved to disk. It appears the midi ends right after the final note event. so, in cases where there's a bit of silence at the end of the input audio clip, this silence is left out of the MIDI data.

Not too familiar with mido, but if I understand correctly, we'd just have to add the correct end_of_file event with the correct time tick value.


My current solution is to inject this event into the midi objects like this:

def add_end_time_to_midi(mid, duration_seconds, default_tempo=500000):
    """
    Adds an empty event at the end of each track to ensure correct MIDI duration.

    Args:
        mid: mido.MidiFile object
        duration_seconds: desired duration in seconds
        default_tempo: tempo to use if none found in file (default: 500000 microseconds per beat)
    Returns:
        mido.MidiFile with correct end time
    """
    # Find tempo from the file or use default
    tempo = default_tempo
    for track in mid.tracks:
        for msg in track:
            if msg.type == 'set_tempo':
                tempo = msg.tempo
                break

    # Calculate total ticks needed
    total_ticks = int(duration_seconds * 1000000 * mid.ticks_per_beat / tempo)

    for track in mid.tracks:
        current_ticks = sum(msg.time for msg in track)
        if current_ticks < total_ticks:
            # Add empty meta message at the end
            from mido import MetaMessage
            track.append(MetaMessage('end_of_track', time=total_ticks - current_ticks))

    return mid
mimbres commented 1 day ago

@nateraw Thank you for your error report and quick fix! I didn’t know that the end_of_track message was necessary, but I learned it from you👍.

Honestly, I’m so busy these days that I can’t make any promises, but I’ll definitely reflect it in the next update. Thanks again!