def save_midi_file(self):
        if len(self.messages_captured) == 0:
            return

        my_midi = MIDIFile(2)
        track = 0

        my_midi.addTrackName(track, 0, "Tempo track")
        my_midi.addTempo(track, 0, self.bpm)

        track += 1
        my_midi.addTrackName(track, 0, "Song track")

        total_time = 0
        midi_messages_on = []
        midi_messages_off = []
        midi_messages_controller = []

        for message in self.messages_captured:
            if len(message) != 3:
                self.write_message("wrong length: skipping " + str(message))
                continue

            total_time += message.time_stamp
            # seconds -> beat conversion
            total_time_adjusted = total_time * float(self.bpm) / float(60)

            if message.type == MidiEventTypes.NOTE_ON:
                midi_messages_on.append(
                    {'note': message[1], 'velocity': message[2], 'time': total_time_adjusted, 'channel': message.channel})
            elif message.type == MidiEventTypes.NOTE_OFF:
                midi_messages_off.append(
                    {'note': message[1], 'velocity': message[2], 'time': total_time_adjusted, 'channel': message.channel})
            elif message.type == MidiEventTypes.CONTROL_CHANGE:
                midi_messages_controller.append(
                    {'type': message[1], 'value': message[2], 'time': total_time_adjusted, 'channel': message.channel})
            else:
                self.write_message("unknown message: skipping " + str(message))
                continue

        for m_on in midi_messages_on:
            for m_off in midi_messages_off:
                if m_off['note'] == m_on['note'] and m_off['time'] > m_on['time']:
                    m_on['duration'] = m_off['time'] - m_on['time']
                    m_off['note'] = -1
                    break
            else:
                m_on['duration'] = float(
                    15) * float(self.bpm) / float(60)  # suspended

        for m in midi_messages_on:
            my_midi.addNote(
                track, m['channel'], m['note'], m['time'], m['duration'], m['velocity'])

        for m in midi_messages_controller:
            my_midi.addControllerEvent(
                track, m['channel'], m['time'], m['type'], m['value'])

        file_name = self.midi_file_name.format(
            datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        file_path = os.path.join(os.path.dirname(sys.argv[0]), file_name)
        self.write_message("Saving {0} MIDI messages to {1}...".format(
            len(self.messages_captured), file_name))
        binfile = open(file_path, 'wb')
        my_midi.writeFile(binfile)
        binfile.close()
        self.messages_captured = []
        self.write_message("Saved.")