Example #1
0
def CreateDroneMidiFile(data_array, name):
    print("creating Drone " + name + " midi file")
    midiObj = MIDIFile(3)  # create one track
    midiObj.addTempo(0, 0, 150)

    #               track, channel, pitch, time      , duration      , volume
    midiObj.addNote(0, 0, 48, 0, len(data_array) / 4, 100)
    midiObj.addNote(1, 0, 55, 0, len(data_array) / 4, 100)
    midiObj.addNote(2, 0, 60, 0, len(data_array) / 4, 100)

    for i, pitch in enumerate(data_array):
        forward = i / 4
        ######## HIGH TONIC NOTE PITCHBEND ####################
        midiObj.addPitchWheelEvent(0, 0, forward,
                                   scale_and_randomize(pitch, 7000))

        ######## DOMINANT NOTE PITCHBEND ######################
        midiObj.addPitchWheelEvent(1, 0, forward,
                                   scale_and_randomize(pitch, 6000))

        #######  LOW TONIC NOTE PITCHBEND #####################
        # midiObj.addPitchWheelEvent(2, 0, note_division, scale_and_randomize(pitch))

    with open("midiFiles/" + name + ".mid", "wb") as midiFile:
        midiObj.writeFile(midiFile)
Example #2
0
def createArpegiatedMidiFile(data_array, name):
    midiObj = MIDIFile(3)  # create one track
    midiObj.addTempo(0, 0, 150)

    for i, pitch in enumerate(data_array):
        forward = i * 2
        ######## HIGH TONIC NOTE ####################
        #               track, channel, pitch, time      , duration    , volume
        midiObj.addNote(0, 0, 48, (forward + i) / 4, SIXTEEN_NOTE, 100)
        midiObj.addPitchWheelEvent(0, 0, (forward + i) / 4,
                                   scale_and_randomize(pitch, 7000))

        ######## DOMINANT NOTE ######################
        midiObj.addNote(1, 0, 55, (forward + i + 1) / 4, SIXTEEN_NOTE, 100)
        midiObj.addPitchWheelEvent(1, 0, (forward + i + 1) / 4,
                                   scale_and_randomize(pitch, 6000))

        #######  LOW TONIC NOTE #####################
        midiObj.addNote(2, 0, 60, (forward + i + 2) / 4, SIXTEEN_NOTE, 100)
        # midiObj.addPitchWheelEvent(2, 0, note_division, scale_and_randomize(pitch))

    with open("midiFiles/" + name + ".mid", "wb") as midiFile:
        midiObj.writeFile(midiFile)
Example #3
0
def create_midi_with_melody(clean_data, alert_data, name, arpegiation):
    midiObj = MIDIFile(4)  # create one track
    midiObj.addTempo(0, 0, 150)

    ####################################################################
    ##################  CREATE ARPEGGIATION  ###########################
    ####################################################################

    if (arpegiation == True):
        clean_rhythm_length = round(len(clean_data) / 16)
        note_cutoff = 0.02

        for i in range(clean_rhythm_length):
            forward = i * 4
            #               track, channel, pitch, time      , duration    , volume
            midiObj.addNote(0, 0, note["c1"], forward,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(2, 0, note["c3"], forward + SIXTEEN_NOTE * 2,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 3,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(0, 0, note["c1"], forward + SIXTEEN_NOTE * 4,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 5,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(2, 0, note["c3"], forward + SIXTEEN_NOTE * 6,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 7,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(0, 0, note["c1"], forward + SIXTEEN_NOTE * 8,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 9,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(2, 0, note["c3"], forward + SIXTEEN_NOTE * 10,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 11,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(0, 0, note["c1"], forward + SIXTEEN_NOTE * 12,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 13,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(2, 0, note["c3"], forward + SIXTEEN_NOTE * 14,
                            SIXTEEN_NOTE - note_cutoff, 100)
            midiObj.addNote(1, 0, note["g2"], forward + SIXTEEN_NOTE * 15,
                            SIXTEEN_NOTE - note_cutoff, 100)

    ####################################################################
    ##################  CREATE DRONE ###################################
    ####################################################################

    else:
        duration = len(clean_data) / 4
        #               track, channel, pitch, time      , duration    , volume
        midiObj.addNote(0, 0, note["c2"], 0, duration, 100)
        midiObj.addNote(1, 0, note["g2"], 0, duration, 100)
        midiObj.addNote(2, 0, note["c1"], 0, duration, 100)

    ####################################################################
    ##################  CREATE PTICH BEND ##############################
    ####################################################################

    pitch_bend_ceiling = [0, 0, 0]
    max_shift = 8192
    previous_data_point = 0
    for i, data_point in enumerate(clean_data):
        note_position = i / 4

        if (previous_data_point == 0.0 and data_point > 0.0):
            pitch_bend_ceiling[0] = int(
                round(max_shift * random.uniform(-1.0, 1.0)))
            pitch_bend_ceiling[1] = int(
                round(max_shift * random.uniform(-1.0, 1.0)))
            pitch_bend_ceiling[2] = int(
                round(max_shift * random.uniform(-1.0, 1.0)))
        elif (previous_data_point > 0 and data_point == 0.0):
            pitch_bend_ceiling = [0, 0, 0]

        ######## HIGH TONIC NOTE PITCHBEND ####################
        #                          track, channel, time         , pitchWheelValue
        midiObj.addPitchWheelEvent(0, 0, note_position, pitch_bend_ceiling[0])
        midiObj.addPitchWheelEvent(1, 0, note_position, pitch_bend_ceiling[1])
        midiObj.addPitchWheelEvent(2, 0, note_position, pitch_bend_ceiling[2])

        previous_data_point = data_point

    ####################################################################
    ##################  CREATE MELODY ##################################
    ####################################################################

    melody_pitches1 = [
        note["c5"],
        note["c5"],
        note["c5"],
        note["c5"],
        note["c5"],
        note["c5"],
        note["c5"],
        note["c5"],
        note["c6"],
        note["c6"],
        note["c6"],
        note["c6"],
        note["c6"],
        note["c6"],
        note["c6"],
        note["c6"],
    ]

    melody_rhythm1 = [
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
    ]

    melody_pitches2 = [
        note["c5"],
        note["cs5"],
        note["d5"],
        note["ds5"],
        note["e5"],
        note["f5"],
        note["fs5"],
        note["c6"],
        note["cs6"],
        note["d6"],
        note["ds6"],
        note["e6"],
        note["f6"],
        note["fs6"],
        note["c5"],
        note["cs5"],
        note["d5"],
        note["ds5"],
        note["e5"],
        note["f5"],
        note["fs5"],
        note["c6"],
        note["cs6"],
        note["d6"],
        note["ds6"],
        note["e6"],
        note["f6"],
        note["fs6"],
    ]

    melody_rhythm2 = [
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
        SIXTEEN_NOTE,
    ]

    melody_pitches3 = [
        note["c5"], note["fs5"], note["cs6"], note["gs6"], note["ds7"],
        note["as7"], note["ds7"], note["gs6"], note["cs6"], note["gs5"],
        note["c5"], note["f4"]
    ]

    melody_rhythm3 = [
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
        EIGHTH_NOTE,
    ]

    midiObj = createMelody(melody_pitches2, melody_rhythm2, alert_data,
                           midiObj, 3)
    # midiObj = createMelody(melody_pitches2, melody_rhythm2, alert_data, midiObj, 3)
    # midiObj = createMelody(melody_pitches3, melody_rhythm3, alert_data, midiObj, 3)

    with open("midiFiles/" + name + ".mid", "wb") as midiFile:
        midiObj.writeFile(midiFile)
Example #4
0
                    pb = 0
                    pb = (pb << 7) + (thisEvent.valueA & 0x7F)
                    pb = (pb << 7) + (thisEvent.valueB & 0x7F)
                    pitchWheelValue = -8192 + pb

                    if (bOverridePitchBend):
                        pitchWheelValue *= pitchBendMultiplier
                        # Correct any overshoot
                        if (pitchWheelValue < -8192): pitchWheelValue = -8192
                        if (pitchWheelValue > 8191): pitchWheelValue = 8191
                        debugPrint(
                            "Adjusted pitchWheelValue is: {}({})".format(
                                pitchWheelValue, hex(pitchWheelValue)))

                    midiFileData.addPitchWheelEvent(0, midiChl,
                                                    thisEvent.time - baseTime,
                                                    pitchWheelValue)
                    midiSection.bHasMIDI = True
                elif (midiCmd == 0xF1):
                    debugPrint("Found end of buffer")
                    break
                elif ((midiCmd >= 0x30 and midiCmd <= 0x3F) or midiCmd == 0x60
                      or midiCmd == 0x11 or midiCmd == 0x12):
                    # These tend to be at the start of blocks we are not interested in
                    debugPrint("Unknown bytes: {}".format(hex(midiCmd)))
                    break
                else:
                    # Not seen this command byte before so dump some context for debugging
                    # purposes then exit
                    s.pos -= (64 * 8)
                    dumphex(68, s)
Example #5
0
class Pat2Midi:
    """
    class to convert Pattern to Midi
    """
    def __init__(self,
                 num_tracks: int = 1,
                 remove_duplicates: bool = True,
                 deinterleave: bool = True,
                 file_format: int = 1):
        """

        :param num_tracks: number of tracks (default: 1)
        :param remove_duplicates: remove notes if they start at the same time on the same channel if they have
               the same pitch  (default: True)
        :param deinterleave: clean up two note-ons with no note-off in between (default: True)
        :param file_format: 1 or 2 (default: 1)
        """
        self.midiFile = MIDIFile(numTracks=num_tracks,
                                 removeDuplicates=remove_duplicates,
                                 deinterleave=deinterleave,
                                 adjust_origin=False,
                                 file_format=file_format)
        self.last_set_tempo = [Defaults.tempo for _ in range(16)
                               ]  # set every track to default tempo
        self.set_tempo(Defaults.tempo, 0)
        self.last_set_cc = [[None for _ in range(NO_OF_CONTROLLERS)]
                            for _ in range(NO_OF_TRACKS)]
        self.note2midi = Note2Midi()

    def set_tempo(self, tempo=100, time=0):
        """

        :param tempo: bpm (default: 100)
        :param time: time at which the tempo change should be inserted in the midi stream (default: 0)
        """
        self.midiFile.addTempo(track=0, time=time, tempo=tempo)
        self.last_set_tempo[0] = tempo
        self.last_set_cc = [[None for _ in range(NO_OF_CONTROLLERS)]
                            for _ in range(NO_OF_TRACKS)]

    def add_phrase(self, phrase: Phrase, track=0, channel=0, start_time=0):
        """

        :param phrase: a Phrase containing patterns and animations
        :param track: default: 0
        :param channel: default: 0
        :param start_time: time at which the phrase should be inserted default: 0
        :return: total duration of the inserted phrase
        """
        for event in phrase:
            # set tempo events only if they changed since last time
            # handle note events
            if PP.NOTE in event:
                if event[PP.TEMPO] != self.last_set_tempo[track]:
                    self.midiFile.addTempo(
                        track, start_time + phrase.generated_duration(),
                        event[PP.TEMPO])
                    self.last_set_tempo[track] = event[PP.TEMPO]
                # set notes always
                if isinstance(event[PP.NOTE], Pchord):
                    for n in event[PP.NOTE].notes:
                        try:
                            intnote = int(n)
                        except ValueError:
                            intnote = self.note2midi.lookup(n)
                            if intnote == REST:
                                continue

                        self.midiFile.addNote(
                            track=track,
                            channel=channel,
                            pitch=intnote,
                            time=start_time + phrase.generated_duration() +
                            event[PP.LAG],
                            duration=event[PP.DUR] * event[PP.PLAYEDDUR],
                            volume=int(event[PP.VOL]),
                            annotation=None)

                else:

                    try:
                        intnote = int(event[PP.NOTE])
                    except ValueError:
                        intnote = self.note2midi.lookup(event[PP.NOTE])
                        if intnote == REST:
                            continue

                    self.midiFile.addNote(
                        track=track,
                        channel=channel,
                        pitch=intnote,
                        time=start_time + phrase.generated_duration() +
                        event[PP.LAG],
                        duration=event[PP.DUR] * event[PP.PLAYEDDUR],
                        volume=int(event[PP.VOL]),
                        annotation=None)

                self.handle_control_changes(channel, event, phrase, start_time,
                                            track)

            # handle controller events (only if they changed since last time)
            else:
                self.handle_control_changes(channel, event, phrase, start_time,
                                            track)

        return phrase.generated_duration()

    def handle_control_changes(self, channel, event, phrase, start_time,
                               track):
        """
        iterate over all control changes in the phrase and add them to the midi file
        :param channel: midi channel
        :param event: python dict containing phrase properties
        :param phrase:
        :param start_time: time offset
        :param track: midi track id
        :return:
        """
        for cc in range(NO_OF_OFFICIAL_CONTROLLERS):
            if PP.ctrl_dur_key(cc) in event:
                time = start_time + phrase.generated_ctrl_duration(cc)
                value = event[PP.ctrl_val_key(cc)]
                if value is not None:
                    self.midiFile.addControllerEvent(track=track,
                                                     channel=channel,
                                                     time=time,
                                                     controller_number=cc,
                                                     parameter=value)
        for cc in [MidiControlChanges.PitchWheel]:
            if PP.ctrl_dur_key(cc) in event:
                time = start_time + phrase.generated_ctrl_duration(cc)
                pwvalue = event[PP.ctrl_val_key(cc)]
                if pwvalue is not None:
                    self.midiFile.addPitchWheelEvent(track=track,
                                                     channel=channel,
                                                     time=time,
                                                     pitchWheelValue=pwvalue)

    def add_phrases(self, list_of_phrase, track=0, channel=0, start_time=0):
        """

        :param list_of_phrase: a list of Phrase
        :param track: default: 0
        :param channel: midi channel, deafult: 0
        :param start_time: default: 0
        :return: total duration of piece from begin until end of list of phrases
        """
        time_delta = 0
        for phrase in list_of_phrase:
            duration = self.add_phrase(phrase, track, channel,
                                       start_time + time_delta)
            time_delta += duration
        return start_time + time_delta

    def write(self, filename):
        """
        write to midi file
        :param filename: filename
        """
        try:
            with open(filename, "wb") as f:
                self.midiFile.writeFile(fileHandle=f)
        except Exception as e:
            print("we hit a SNAFU while writing to {0}: {1}".format(
                filename, e))