Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ease of use for DAW MIDI tracks #26

Open
claytonsulby opened this issue Jun 28, 2020 · 2 comments
Open

Ease of use for DAW MIDI tracks #26

claytonsulby opened this issue Jun 28, 2020 · 2 comments
Assignees

Comments

@claytonsulby
Copy link

Moving the midi files into a DAW and assigning instruments for a track is a timely endeavor with a few solutions. Here's one I've come up with, that I'd love to see implemented to speed up the process.

  1. trim the whitespace in the beginning of a new section and,
  2. rearrange the naming convention to place instrument first, section second.
    (This will allow for easy moving by sorting by name.)

Another thought is to find a way to assign a name to the track. When imported into the DAW each midi file is named "Track 0" regardless of placement.

@amchaney amchaney self-assigned this Jun 29, 2020
@amchaney
Copy link
Collaborator

I haven't worked on this project in a while, but I've been thinking about it a lot recently! Thanks for the suggestion. I assigned it to me, but if there is anyone else out there in the wide wide open source world who feels like doing this, please feel free to pick it up

@duringleaves
Copy link

duringleaves commented May 9, 2024

I've tried writing a script to merge the separated instrument section midi's into a single midi file, but I'm hitting a wall on getting the note timing of the secondary sections correct. MIDI timing, as I understand it, is based on a duration of ticks from the previous note. Each new section contains a 0-velocity, 1-tick note event at the start and then silence so the notes are aligned properly, but I just can't get the fiddling right to simply append the additional sections at their correct timing.

Here's my code at the moment if anyone feels like taking a stab at it:

import os
from mido import MidiFile, MidiTrack

def list_midi_files(directory):
    """List all MIDI files in the directory."""
    return [f for f in os.listdir(directory) if f.endswith('.mid')]

def group_files_by_instrument(files):
    """Group files by the part of the instrument name."""
    grouped_files = {}
    for file in files:
        parts = file.split('_')
        instrument_name = '_'.join(parts[3:])
        if instrument_name not in grouped_files:
            grouped_files[instrument_name] = []
        grouped_files[instrument_name].append(file)
    return grouped_files

def merge_midi_files(directory, files):
    """Merge MIDI files by adjusting start times based on the previous section's duration."""
    combined_track = MidiTrack()
    last_note_off_time = 0  # Time of the last note_off

    for index, file in enumerate(sorted(files)):
        mid = MidiFile(os.path.join(directory, file))
        track = mid.tracks[0]
        current_time = 0  # Current time counter for the track

        print(f"Processing file: {file}") # debugging
        for msg in track:
            if msg.type in ['note_on', 'note_off']:
                current_time += msg.time
                if index > 0:  # Adjust the message time for all but the first file
                    adjusted_time = current_time - last_note_off_time
                    msg.time = max(0, adjusted_time)  # Ensure no negative times
                    print(f"Adjusted msg: {msg} with adjusted_time: {adjusted_time}")   # debugging
                combined_track.append(msg)

                if msg.type == 'note_off':
                    last_note_off_time = current_time  # Update the last note_off time

        print(f"Last note_off_time for {file}: {last_note_off_time}") # debugging

    new_mid = MidiFile()
    new_mid.tracks.append(combined_track)
    return new_mid

def main(directory):
    midi_files = list_midi_files(directory)
    grouped_files = group_files_by_instrument(midi_files)
    for instrument, files in grouped_files.items():
        merged_midi = merge_midi_files(directory, files)
        # Save the merged MIDI file
        merged_filename = os.path.join(directory, f"{instrument}_merged.mid")
        merged_midi.save(merged_filename)
        print(f"Merged file created: {merged_filename}")

if __name__ == "__main__":
    directory = '/AI/Projects/watson-beat/src/output/MIDIFiles/'  # Specify the directory
    main(directory)
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants