Exemplo n.º 1
0
def parse_nottingham_to_sequence(input_filename, time_step, verbose=False):
    """
    input_filename: a MIDI filename

    returns a [T x D] matrix representing a sequence with T time steps over
    D dimensions
    """
    sequence = []
    pattern = midi.read_midifile(input_filename)

    metadata = {
        "path": input_filename,
        "name": input_filename.split("/")[-1].split(".")[0]
    }

    # Most nottingham midi's have 3 tracks. metadata info, melody, harmony
    # throw away any tracks that don't fit this
    if len(pattern) != 3:
        if verbose:
            "Skipping track with {} tracks".format(len(pattern))
        return (metadata, None)

    # ticks_per_quarter = -1
    for msg in pattern[0]:
        if isinstance(msg, midi.TimeSignatureEvent):
            metadata["ticks_per_quarter"] = msg.get_metronome()
            ticks_per_quarter = msg.get_metronome()

    if verbose:
        print ("{}".format(input_filename)))
        print ("Track resolution: {}".format(pattern.resolution))
        print ("Number of tracks: {}".format(len(pattern)))
        print ("Time step: {}".format(time_step))
        print ("Ticks per quarter: {}".format(ticks_per_quarter))

    # Track ingestion stage
    track_ticks = 0

    melody_notes, melody_ticks = midi_util.ingest_notes(pattern[1])
    harmony_notes, harmony_ticks = midi_util.ingest_notes(pattern[2])

    track_ticks = midi_util.round_tick(max(melody_ticks, harmony_ticks), time_step)
    if verbose:
        print ("Track ticks (rounded): {} ({} time steps)".format(track_ticks, track_ticks/time_step))
    
    melody_sequence = midi_util.round_notes(melody_notes, track_ticks, time_step, 
                                  R=NOTTINGHAM_MELODY_RANGE, O=NOTTINGHAM_MELODY_MIN)
Exemplo n.º 2
0
def parse_nottingham_to_sequence(input_filename, time_step, verbose=False):
    """
    input_filename: a MIDI filename

    returns a [T x D] matrix representing a sequence with T time steps over
    D dimensions
    """
    sequence = []
    pattern = midi.read_midifile(input_filename)

    metadata = {
        "path": input_filename,
        "name": input_filename.split("/")[-1].split(".")[0]
    }

    # Most nottingham midi's have 3 tracks. metadata info, melody, harmony
    # throw away any tracks that don't fit this
    if len(pattern) != 3:
        if verbose:
            "Skipping track with {} tracks".format(len(pattern))
        return (metadata, None)

    # ticks_per_quarter = -1
    for msg in pattern[0]:
        if isinstance(msg, midi.TimeSignatureEvent):
            metadata["ticks_per_quarter"] = msg.get_metronome()
            ticks_per_quarter = msg.get_metronome()

    if verbose:
        print("{}".format(input_filename))
        print("Track resolution: {}".format(pattern.resolution))
        print("Number of tracks: {}".format(len(pattern)))
        print("Time step: {}".format(time_step))
        print("Ticks per quarter: {}".format(ticks_per_quarter))

    # Track ingestion stage
    track_ticks = 0

    melody_notes, melody_ticks = midi_util.ingest_notes(pattern[1])
    harmony_notes, harmony_ticks = midi_util.ingest_notes(pattern[2])

    track_ticks = midi_util.round_tick(max(melody_ticks, harmony_ticks),
                                       time_step)
    if verbose:
        print("Track ticks (rounded): {} ({} time steps)".format(
            track_ticks, track_ticks / time_step))

    melody_sequence = midi_util.round_notes(melody_notes,
                                            track_ticks,
                                            time_step,
                                            R=NOTTINGHAM_MELODY_RANGE,
                                            O=NOTTINGHAM_MELODY_MIN)

    for i in range(melody_sequence.shape[0]):
        if np.count_nonzero(melody_sequence[i, :]) > 1:
            if verbose:
                print("Double note found: {}: {} ({})".format(
                    i, np.nonzero(melody_sequence[i, :]), input_filename))
            return (metadata, None)

    harmony_sequence = midi_util.round_notes(harmony_notes, track_ticks,
                                             time_step)

    harmonies = []
    for i in range(harmony_sequence.shape[0]):
        notes = np.where(harmony_sequence[i] == 1)[0]
        if len(notes) > 0:
            notes_shift = [
                mingus.core.notes.int_to_note(h % 12) for h in notes
            ]
            chord = mingus.core.chords.determine(notes_shift, shorthand=True)
            if len(chord) == 0:
                # try flat combinations
                notes_shift = [
                    SHARPS_TO_FLATS[n] if n in SHARPS_TO_FLATS else n
                    for n in notes_shift
                ]
                chord = mingus.core.chords.determine(notes_shift,
                                                     shorthand=True)
            if len(chord) == 0:
                if verbose:
                    print("Could not determine chord: {} ({}, {}), defaulting to last steps chord" \
                          .format(notes_shift, input_filename, i))
                if len(harmonies) > 0:
                    harmonies.append(harmonies[-1])
                else:
                    harmonies.append(NO_CHORD)
            else:
                resolved = resolve_chord(chord[0])
                if resolved:
                    harmonies.append(resolved)
                else:
                    harmonies.append(NO_CHORD)
        else:
            harmonies.append(NO_CHORD)

    return (metadata, (melody_sequence, harmonies))
Exemplo n.º 3
0
def Data_to_Sequence(midFile, timeStep):
    unkChord = 'NONE'  # for unknown chords
    harmony = []
    # get MIDI evet messages from each file
    midData = midi.read_midifile(midFile)

    # store file path and name as meta info
    meta = {"path": midFile, "name": midFile.split("/")[-1].split(".")[0]}
    # check for length , 3 tracks for meta , melody and harmony
    if len(midData) != 3:
        return (meta, None)

    for msg in midData[0]:

        if isinstance(msg, midi.TimeSignatureEvent):
            # get PPQN (Pulse per Quarter Note)for MIDI resolution
            meta["ticks_per_quarter_note"] = msg.get_metronome()

            # get time signature values
            num = midData[0][2].data[0]
            dem = 2**(midData[0][2].data[1])
            sig = (num, dem)
            meta["signature"] = sig

            # Measure time signatur frequency
            if sig not in sigs:
                sigs[sig] = 1
            else:
                sigs[sig] += 1

            # Filter out sequences with time signature 4/4 based on flag
            if fourByFour == True:
                if (num == 3 or num == 6) or (dem != 4):
                    return (meta, None)

    # Track ingestion
    nTicks = 0

    # get melody and harmony notes and ticks from midi Data
    melNotes, melTicks = midi_util.ingest_notes(midData[1])
    harNotes, harTicks = midi_util.ingest_notes(midData[2])

    # round number of ticks with given time step value
    nTicks = midi_util.round_tick(max(melTicks, harTicks), timeStep)

    # get melody encodings mapped to defined melody range
    melSequence = midi_util.round_notes(melNotes,
                                        nTicks,
                                        timeStep,
                                        R=melodyRange,
                                        O=melodyMin)

    # filter out sequences with a double note is found in melody
    for i in range(melSequence.shape[0]):
        if np.count_nonzero(melSequence[i, :]) > 1:
            return (meta, None)

    # get harmony sequence and process with Mingus
    harSequence = midi_util.round_notes(harNotes, nTicks, timeStep)

    # convert sharps to flats to consider compositional considerations
    flat_note = {
        "A#": "Bb",
        "B#": "C",
        "C#": "Db",
        "D#": "Eb",
        "E#": "F",
        "F#": "Gb",
        "G#": "Ab",
    }

    # use Mingus to identify chords from harmony notes
    for i in range(harSequence.shape[0]):

        # get note data
        notes = np.where(harSequence[i] == 1)[0]
        if len(notes) > 0:

            # get note names without octave information
            noteName = [
                mingus.core.notes.int_to_note(note % 12) for note in notes
            ]
            chordName = mingus.core.chords.determine(noteName, shorthand=True)

            if len(chordName) == 0:
                # convert to flat if chord not identified and try again
                noteName = [
                    flat_note[n] if n in flat_note else n for n in noteName
                ]
                chordName = mingus.core.chords.determine(noteName,
                                                         shorthand=True)

            if len(chordName) == 0:
                # if chord does not exist, label as NONE
                if len(harmony) > 0:
                    harmony.append(harmony[-1])
                else:
                    harmony.append(unkChord)

            # resolve chords as major or minor for other types of chord
            else:
                resolvedChord = Resolve_Chords(chordName[0])
                if resolvedChord:
                    harmony.append(resolvedChord)
                else:
                    harmony.append(unkChord)
        else:
            # label as unresolve after all attempts
            harmony.append(unkChord)

    return (meta, (melSequence, harmony))
Exemplo n.º 4
0
def parse_nottingham_to_sequence(input_filename, time_step, verbose=False):
    """
    input_filename: a MIDI filename

    returns a [T x D] matrix representing a sequence with T time steps over
    D dimensions
    """
    sequence = []
    pattern = midi.read_midifile(input_filename)

    metadata = {
        "path": input_filename,
        "name": input_filename.split("/")[-1].split(".")[0]
    }

    # Most nottingham midi's have 3 tracks. metadata info, melody, harmony
    # throw away any tracks that don't fit this
    if len(pattern) != 3:
        if verbose:
            "Skipping track with {} tracks".format(len(pattern))
        return (metadata, None)

    # ticks_per_quarter = -1
    for msg in pattern[0]:
        if isinstance(msg, midi.TimeSignatureEvent):
            metadata["ticks_per_quarter"] = msg.get_metronome()
            ticks_per_quarter = msg.get_metronome()

    if verbose:
        print "{}".format(input_filename)
        print "Track resolution: {}".format(pattern.resolution)
        print "Number of tracks: {}".format(len(pattern))
        print "Time step: {}".format(time_step)
        print "Ticks per quarter: {}".format(ticks_per_quarter)

    # Track ingestion stage
    track_ticks = 0

    melody_notes, melody_ticks = midi_util.ingest_notes(pattern[1])
    harmony_notes, harmony_ticks = midi_util.ingest_notes(pattern[2])

    track_ticks = midi_util.round_tick(max(melody_ticks, harmony_ticks), time_step)
    if verbose:
        print "Track ticks (rounded): {} ({} time steps)".format(track_ticks, track_ticks/time_step)
    
    melody_sequence = midi_util.round_notes(melody_notes, track_ticks, time_step, 
                                  R=NOTTINGHAM_MELODY_RANGE, O=NOTTINGHAM_MELODY_MIN)

    for i in range(melody_sequence.shape[0]):
        if np.count_nonzero(melody_sequence[i, :]) > 1:
            if verbose:
                print "Double note found: {}: {} ({})".format(i, np.nonzero(melody_sequence[i, :]), input_filename)
            return (metadata, None)

    harmony_sequence = midi_util.round_notes(harmony_notes, track_ticks, time_step)

    harmonies = []
    for i in range(harmony_sequence.shape[0]):
        notes = np.where(harmony_sequence[i] == 1)[0]
        if len(notes) > 0:
            notes_shift = [ mingus.core.notes.int_to_note(h%12) for h in notes]
            chord = mingus.core.chords.determine(notes_shift, shorthand=True)
            if len(chord) == 0:
                # try flat combinations
                notes_shift = [ SHARPS_TO_FLATS[n] if n in SHARPS_TO_FLATS else n for n in notes_shift]
                chord = mingus.core.chords.determine(notes_shift, shorthand=True)
            if len(chord) == 0:
                if verbose:
                    print "Could not determine chord: {} ({}, {}), defaulting to last steps chord" \
                          .format(notes_shift, input_filename, i)
                if len(harmonies) > 0:
                    harmonies.append(harmonies[-1])
                else:
                    harmonies.append(NO_CHORD)
            else:
                resolved = resolve_chord(chord[0])
                if resolved:
                    harmonies.append(resolved)
                else:
                    harmonies.append(NO_CHORD)
        else:
            harmonies.append(NO_CHORD)

    return (metadata, (melody_sequence, harmonies))
Exemplo n.º 5
0
def Data_to_Sequence(input_filename, time_step, verbose=False):

    pattern = midi.read_midifile(input_filename)
    metadata = {
        "path": input_filename,
        "name": input_filename.split("/")[-1].split(".")[0]
    }
    if len(pattern) != 3:
        return (metadata, None)
    # ticks_per_quarter = -1
    for msg in pattern[0]:
        
        if isinstance(msg, midi.TimeSignatureEvent):
            metadata["ticks_per_quarter"] = msg.get_metronome()
            num = pattern[0][2].data[0]
            dem  = 2** (pattern[0][2].data[1])
            sig = (num, dem)
            metadata["signature"] = sig
            if sig not in sigs:
                sigs[sig] = 1
            else:
                sigs[sig] += 1
                
            if fourByFour == True:
                if (num == 3 or num == 6) or (dem !=4):

                    return (metadata, None)

    # Track ingestion stage
    track_ticks = 0

    melody_notes, melody_ticks = midi_util.ingest_notes(pattern[1])
    harmony_notes, harmony_ticks = midi_util.ingest_notes(pattern[2])

    track_ticks = midi_util.round_tick(max(melody_ticks, harmony_ticks), time_step)
    if verbose:
        print "Track ticks (rounded): {} ({} time steps)".format(track_ticks, track_ticks/time_step)
    
    melody_sequence = midi_util.round_notes(melody_notes, track_ticks, time_step, 
                                  R=Melody_Range, O=Melody_Min)

    for i in range(melody_sequence.shape[0]):
        if np.count_nonzero(melody_sequence[i, :]) > 1:
            if verbose:
                print "Double note found: {}: {} ({})".format(i, np.nonzero(melody_sequence[i, :]), input_filename)
            return (metadata, None)
        
    harmony_sequence = midi_util.round_notes(harmony_notes, track_ticks, time_step)

    harmonies = []
    flat_note = {"A#": "Bb", "B#": "C", "C#": "Db", "D#": "Eb", "E#": "F", "F#": "Gb", "G#": "Ab",}
    #Identify chords from track 1 notes using mingus library 
    for i in range(harmony_sequence.shape[0]):
        notes = np.where(harmony_sequence[i] == 1)[0]
        if len(notes) > 0:
            notes_shift = [ mingus.core.notes.int_to_note(h%12) for h in notes]
            chord = mingus.core.chords.determine(notes_shift, shorthand=True)
            if len(chord) == 0:
                # try flat combinations
                notes_shift = [ flat_note[n] if n in flat_note else n for n in notes_shift]
                chord = mingus.core.chords.determine(notes_shift, shorthand=True)
            if len(chord) == 0:
                #print "Could not determine chord: {} ({}, {}), defaulting to last steps chord" \
                #          .format(notes_shift, input_filename, i)
                if len(harmonies) > 0:
                    harmonies.append(harmonies[-1])
                else:
                    harmonies.append(unkChord)
            else:
                resolved = resolve_chord(chord[0])
                if resolved:
                    harmonies.append(resolved)
                else:
                    harmonies.append(unkChord)
        else:
            harmonies.append(unkChord)
    return (metadata, (melody_sequence, harmonies))