Exemple #1
0
class Song:
    def __init__(self, tracks, length):
        self.song = None
        self.tracks = tracks
        self.length = length
        self.actual_track = 0
        self.tracks_list = []

    def add_track(self, track):
        self.tracks_list.append(track)

    def save_song(self, output="my_file.mid"):
        self.song = MIDIFile(len(self.tracks_list))
        for t in self.tracks_list:
            self.song.addTempo(self.actual_track, t.start, t.tempo)
            self.add_pitches(t)
            self.actual_track += 1
        with open(output, "wb") as output_file:
            self.song.writeFile(output_file)

    def add_pitches(self, track):
        for list in track.board.values():
            for note in list:
                self.song.addNote(self.actual_track, self.actual_track,
                                  note.get_pitch(), note.time, note.duration,
                                  100)
        self.song.addProgramChange(self.actual_track, self.actual_track,
                                   track.start, track.instrument)
def generate_midi(notes):
    # Create the MIDIFile Object
    MyMIDI = MIDIFile(1)

    # Add track name and tempo. The first argument to addTrackName and
    # addTempo is the time to write the event.
    track = 0
    time = 0
    MyMIDI.addTrackName(track, time, "Sample Track")
    MyMIDI.addTempo(track, time, 120)

    # Add a note. addNote expects the following information:
    channel = 0
    # pitch = 60
    # duration = 1
    volume = 100

    # Now add the note.
    for note in notes:
        MyMIDI.addNote(track, channel, note.pitch, time, note.duration, volume)
        time += note.duration

    # And write it to disk.
    binfile = open("./server_files/output.mid", 'wb')
    MyMIDI.writeFile(binfile)
    binfile.close()
Exemple #3
0
def save_midi(grid, path, click_track=False, click_track_start=0, accent_downbeat=False, period=0, pulse=1, bpm=240, channel=9, pitch=75, velocity=100):
    '''
    bpm means grid-units per second in this case
    '''

    phase, iois = rhythm_tools.grid_to_iois(grid)

    track = 0

    mf = MIDIFile(1)

    mf.addTrackName(track, 0, "Sample Track")
    mf.addTempo(track, 0, bpm)

    rhythm_start = 0

    if click_track: 

        if click_track_start < 0:
            rhythm_start = -click_track_start
            click_track_start = 0

        click_track_end = (
            rhythm_start + len(iois)
        )

        print(rhythm_start, click_track_start)

        write_click_track(mf, start_time=click_track_start, end_time=click_track_end, period=period, pulse=pulse, velocity=velocity, accent_downbeat=accent_downbeat)

    write_iois(mf, iois, start_time=rhythm_start, track=track, channel=channel, pitch=pitch, velocity=velocity)

    with open(path, 'wb') as midi_file:
        mf.writeFile(midi_file)
Exemple #4
0
def create_midi(note_groups):
    midi = MIDIFile(1)

    track = 0
    time = 0
    channel = 0
    volume = 100

    midi.addTrackName(track, time, "Track")
    midi.addTempo(track, time, 140)

    for note_group in note_groups:
        duration = None
        for note in note_group:
            note_type = note.sym
            if note_type == "1":
                duration = 4
            elif note_type == "2":
                duration = 2
            elif note_type == "4,8":
                duration = 1 if len(note_group) == 1 else 0.5
            pitch = note.pitch
            midi.addNote(track, channel, pitch, time, duration, volume)
            time += duration

    #midi.addNote(track,channel,pitch,time,4,0)
    # And write it to disk.
    binfile = open("output.mid", 'wb')
    midi.writeFile(binfile)
    binfile.close()
Exemple #5
0
class Midi:
    """Musique midi"""
    def __init__(self, partition, tempo):
        # Définition des paramètres MIDI.
        piste = 0
        temps = 0
        self.sortieMidi = MIDIFile(1)
        # Nom de la piste.
        self.sortieMidi.addTrackName(piste, temps, "Gregorien")
        # Tempo.
        self.sortieMidi.addTempo(piste, temps, tempo)
        # Instrument (74 : flûte).
        self.sortieMidi.addProgramChange(piste, 0, temps, 74)
        # À partir des propriétés de la note, création des évènements
        # MIDI.
        for note in partition:
            channel = 0
            pitch = note.hauteur
            duree = note.duree
            volume = 127
            self.sortieMidi.addNote(piste, channel, pitch, temps, duree,
                                    volume)
            temps += duree

    def ecrire(self, chemin):
        """Écriture effective du fichier MIDI"""
        binfile = open(chemin, 'wb')
        self.sortieMidi.writeFile(binfile)
        binfile.close()
Exemple #6
0
class Midi:
    """Musique midi"""
    def __init__(self,partition,tempo):
        # Définition des paramètres MIDI.
        piste = 0
        temps = 0
        self.sortieMidi = MIDIFile(1)
        # Nom de la piste.
        self.sortieMidi.addTrackName(piste,temps,"Gregorien")
        # Tempo.
        self.sortieMidi.addTempo(piste,temps, tempo)
        # Instrument (74 : flûte).
        self.sortieMidi.addProgramChange(piste,0,temps,74)
        # À partir des propriétés de la note, création des évènements
        # MIDI.
        for note in partition:
            channel = 0
            pitch = note.hauteur
            duree = note.duree
            volume = 127
            self.sortieMidi.addNote(piste,
                                    channel,
                                    pitch,
                                    temps,
                                    duree,
                                    volume)
            temps += duree
    def ecrire(self,chemin):
        """Écriture effective du fichier MIDI"""
        binfile = open(chemin, 'wb')
        self.sortieMidi.writeFile(binfile)
        binfile.close()
class GenerateMelody(object):
    def __init__(self, file, pitch, length, beat_duration):
        self.pitch = pitch
        self.length = abs(length)
        self.file = file
        self.midi_melody = MIDIFile(1)
        self.beat_duration = abs(beat_duration)

    def get_filename(self):
        if not self.file.endswith(".mid"):
            return self.file + ".mid"
        return self.file

    def get_random_pitch(self):
        step = random.randint(-5, 5)
        return abs(self.pitch + step)

    @staticmethod
    def get_random_volume():
        return random.randint(70, 127)

    def generate(self):
        time = 0

        self.midi_melody.addTempo(0, time, 60)
        while time < self.length:
            self.midi_melody.addNote(0, 0, self.get_random_pitch(), time,
                                     self.beat_duration, self.get_random_volume())
            time += self.beat_duration

        binfile = open(self.get_filename(), 'wb')
        self.midi_melody.writeFile(binfile)
        binfile.close()
def to_midi(events_):
    midistream = MIDIFile(1)

    track = 0
    time = 0
    channel = 0
    volume = 100

    midistream.addTrackName(track, time, "Track")
    midistream.addTempo(track, time, 60)

    temp = []
    for index, event_ in enumerate(events_):
        if event_[0][0] == 144:  #key down
            temp = event_
        elif event_[0][0] == 128:  #key up
            duration = (event_[1] - temp[1]) / 1000
            pitch = event_[0][1]
            time = temp[1] / 1000
            midistream.addNote(track, channel, pitch, time, duration, volume)

    # And write it to disk.
    binfile = open("temp/user_output.mid", 'wb')
    midistream.writeFile(binfile)
    print(midistream)
    binfile.close()
Exemple #9
0
 def make(self):
     with open("output.mid", 'wb') as f:
         MyMIDI = MIDIFile(1)
         track = 0
         time = 0
         channel = 0
         volume = 100
         MyMIDI.addTrackName(track, self.tempo, "Sample Track")
         MyMIDI.addTempo(track, time, 120)
         for part in self.structure:
             for note in self.riffs[part][0].score:
                 MyMIDI.addNote(track, channel, note.pitch, time, note.duration, volume)
                 time += note.duration
         MyMIDI.writeFile(f)
 def createFile(self):
     MIDI = MIDIFile(1)
     MIDI.addTrackName(0,0,self.name)
     MIDI.addTempo(0,0, self.bpm)
     beat = 0
     for chord in self.chords:
         for degree in chord.degrees:
             MIDI.addNote(0,0,self.scale.scaleNotes[degree],beat,1,chord.intensity)
         beat = beat + 1
     if not os.path.exists(songFolder):
       os.makedirs(songFolder)
     midiFile = open("%s/%d.%d-%s.mid"%(songFolder, self.generation, self.songnum, self.name), 'wb')
     MIDI.writeFile(midiFile)
     midiFile.close()
Exemple #11
0
class MIDInotes(object):
    def __init__(self, tempo=120, outfile='midi.mid'):
        self.tempo = tempo
        self.outfile = outfile
        self.tracks = []

    def add_track(self, note_list):
        self.tracks.append(note_list)

    def add_note(self, track, channel, note):
        time = note[0]
        pitch = note[1]
        velocity = note[2]
        duration = note[3]

        # Now add the note.
        self.MIDIFile.addNote(track, channel, pitch, time, duration, velocity)

    def save_midi(self, instrument):
        # Create the MIDIFile Object with 1 track
        self.MIDIFile = MIDIFile(len(self.tracks))
        #self.MIDIFile.addProgramChange(0, 0, 0, instrument)

        for i, note_list in enumerate(self.tracks):

            # Tracks are numbered from zero. Times are measured in beats.
            track = i
            time = 0

            # Add track name, tempo and instrument change event
            self.MIDIFile.addTrackName(track, time, "Track %s" % i)
            self.MIDIFile.addTempo(track, time, self.tempo)
            self.MIDIFile.addProgramChange(track, 0, time, instrument)

            for n in note_list:
                if len(n) == 2:
                    note = n[0]
                    channel = n[1]
                else:
                    note = n
                    channel = 0
                self.add_note(track, channel, note)

        # And write it to disk.
        with open(self.outfile, 'wb') as binfile:
            self.MIDIFile.writeFile(binfile)
def arrayToMidiDouble(aArray, count):
    MyMIDI = MIDIFile(1)
    MyMIDI.addTrackName(0,0,"Red")
    MyMIDI.addTempo(0,0,120)
    time = 0
    for j in range(len(aArray)):
        # randDur = choice([0.5, 0.25, 1, 2, 4])
        randDur = 1
        pitch = aArray[j]
        MyMIDI.addNote(0,0,pitch,time,randDur,100)
        time += randDur
    name = str(count) + ".mid"
    print(name)
    binfile = open(name, 'wb')
    MyMIDI.writeFile(binfile)
    binfile.close()
    print("finishing producing midi")
    return (name)
Exemple #13
0
class MidiWrite(OutputRajapinta):
    def __init__(self, max_tracks, filename):
        self.filename = filename
        self.midi = MIDIFile(max_tracks)

    def nuotti(self, track, channel, pitch, time, duration, volume):
        self.midi.addNote(track, channel, pitch, time, duration, volume)

    def tempo(self, track, time, tempo):
        self.midi.addTempo(track, time, tempo)

    def soitin(self, track, channel, time, program):
        self.midi.addProgramChange(track, channel, time, program)

    def kirjoita(self):
        file = open(self.filename, "wb")
        self.midi.writeFile(file)
        file.close()
Exemple #14
0
class Midi:
    """Musique midi"""
    def __init__(self, partition, titre, tempo):
        # Définition des paramètres MIDI.
        piste = 0
        temps = 0
        self.sortiemidi = MIDIFile(1)
        # Nom de la piste.
        self.sortiemidi.addTrackName(piste, temps, sansaccents(titre))
        # Tempo.
        self.sortiemidi.addTempo(piste, temps, tempo)
        # Instrument (74 : flûte).
        self.sortiemidi.addProgramChange(piste, 0, temps, 74)
        self.traiter_partition(partition, piste, temps)

    def traiter_partition(self, partition, piste, temps):
        """Création des évènements MIDI"""
        transposition = partition.transposition
        for neume in partition.musique:
            for note in (
                    notes for notes in neume if isinstance(notes, Note)
            ):
                channel = 0
                pitch = note.hauteur + transposition
                duree = note.duree
                volume = 127
                self.sortiemidi.addNote(
                    piste,
                    channel,
                    pitch,
                    temps,
                    duree,
                    volume
                )
                temps += duree

    def ecrire(self, chemin):
        """Écriture effective du fichier MIDI"""
        with (
            open(sys.stdout.fileno(), 'wb')
            if chemin == '-'
            else open(chemin, 'wb')
        )as sortie:
            self.sortiemidi.writeFile(sortie)
Exemple #15
0
def save_midi(offset,
              iois,
              pitches,
              path,
              click_track=False,
              click_track_phase=0,
              accent_downbeat=False,
              period=0,
              pulse=1,
              bpm=240,
              channel=0,
              velocity=100):
    '''
    bpm means grid-units per second in this case
    '''

    track = 0

    mf = MIDIFile(1)

    mf.addTrackName(track, 0, "Sample Track")
    mf.addTempo(track, 0, bpm)

    if click_track:

        duration = offset + sum(iois)
        write_click_track(mf,
                          duration,
                          phase=click_track_phase,
                          period=period,
                          pulse=pulse,
                          velocity=velocity,
                          accent_downbeat=accent_downbeat)

    write_notes(mf,
                offset,
                iois,
                pitches,
                track=track,
                channel=channel,
                velocity=velocity)

    with open(path, 'wb') as midi_file:
        mf.writeFile(midi_file)
Exemple #16
0
def midiSing(sheet, instruments, key, ticktime, filename):
    offset = NOTES.index(key) + 60 # Middle C is MIDI note #60    
    midi=MIDIFile(len(sheet))
    replaceprint('Creating midi...')
    for t in range(0,len(sheet)): 
        midi.addTrackName(t, 0, "Track %s"%t)
        midi.addTempo(t, 0, 60000/(ticktime))
        sheet[t]=sheet[t][1:]+[(sheet[t][0],0)]
        tracklen=len(sheet[t])
        for n in range(0,tracklen-1):
            time, note = sheet[t][n]
            duration = sheet[t][(n+1)%tracklen][0]-time
            midi.addNote(t,0,offset+note,time,duration,100)#MyMIDI.addNote(track,channel,pitch,time,duration,volume)
    replaceprint('Writing to file...')
    binfile = open(filename+".mid", 'wb')
    midi.writeFile(binfile)
    binfile.close()
    replaceprint('Synth complete!')
    print("\nMID output to: \"" + filename+ ".mid\"")
    def midi(self, path, bpm=240, channel=9, pitch=75, velocity=100):

        from midiutil.MidiFile3 import MIDIFile

        track = 0
        time = 0

        mf = MIDIFile(1)

        mf.addTrackName(track, time, "Sample Track")
        mf.addTempo(track, time, bpm)

        for duration in self.durations:

            mf.addNote(track, channel, pitch, time, duration, velocity)
            time += duration

        # write it to disk
        with open(path, 'wb') as midi_file:
            mf.writeFile(midi_file)
Exemple #18
0
def midiSing(sheet, instruments, key, ticktime, filename):
    offset = NOTES.index(key) + 60  # Middle C is MIDI note #60
    midi = MIDIFile(len(sheet))
    replaceprint('Creating midi...')
    for t in range(0, len(sheet)):
        midi.addTrackName(t, 0, "Track %s" % t)
        midi.addTempo(t, 0, 60000 / (ticktime))
        sheet[t] = sheet[t][1:] + [(sheet[t][0], 0)]
        tracklen = len(sheet[t])
        for n in range(0, tracklen - 1):
            time, note = sheet[t][n]
            duration = sheet[t][(n + 1) % tracklen][0] - time
            midi.addNote(
                t, 0, offset + note, time, duration,
                100)  #MyMIDI.addNote(track,channel,pitch,time,duration,volume)
    replaceprint('Writing to file...')
    binfile = open(filename + ".mid", 'wb')
    midi.writeFile(binfile)
    binfile.close()
    replaceprint('Synth complete!')
    print("\nMID output to: \"" + filename + ".mid\"")
Exemple #19
0
def construct_midi(filename, bpm, trackname, beat_intervals):
	# Create a MIDI with one track
	MyMIDI = MIDIFile(1)

	track = 0 
	time = 0
	MyMIDI.addTrackName(track, time, trackname) 
	MyMIDI.addTempo(track, time, bpm)

	TIME_COUNTER = 0

	for beat_interval in beat_intervals:
		acappella_measure = chord_from_beat(beat_interval)
		TIME_COUNTER = _add_measure(
			acappella_measure, 
			TIME_COUNTER, 
			MyMIDI
		)

	binfile = open("../output/" + filename, 'wb') 
	MyMIDI.writeFile(binfile) 
	binfile.close()
Exemple #20
0
class MidiPlay(OutputRajapinta):
    def __init__(self, max_tracks, filename):
        self.midi = MIDIFile(max_tracks)

    def nuotti(self, track, channel, pitch, time, duration, volume):
        self.midi.addNote(track, channel, pitch, time, duration, volume)

    def tempo(self, track, time, tempo):
        self.midi.addTempo(track, time, tempo)

    def soitin(self, track, channel, time, program):
        self.midi.addProgramChange(track, channel, time, program)

    def kirjoita(self, file=None):
        import sys
        import io

        # Systeemialustan mukainen miditiedoston soittamiseen käytetty tiedosto
        if sys.platform == "win32":
            from mplaymaster.win32midi import midiDevice
        elif sys.platform == "darwin":
            from mplaymaster.darwinmidi import midiDevice
        else:
            raise ImportError(
                "Sori, soitto ei tue muuta kuin Windowsia ja Mac OS X:ää :(")

        # Haetaan soittolaite tiedoston alussa importatusta kirjastosta
        laite = midiDevice()

        # Luodaan BytesIO-objekti, joka toimii kuin bytes-tilassa avattu tiedosto
        tiedosto = file if file is not None else io.BytesIO()
        self.midi.writeFile(tiedosto)
        tiedosto.seek(0)

        # Ja kutsutaan laitteen soittofunktiota omassa säikeessään. Tämä tehdään siksi, että
        # ohjelma pääsee jatkamaan suoritustaan musiikin soidessa taustalla.
        laite.play(tiedosto)
time_since_root = 0
this_time = 0.0
note_durations = []
note_times = []
elongation_factor = 1.5
for i in xrange(len(signature)):
    if signature[i] == 0:
        root_interval_ind += 1
        time_since_root = 0
        this_time = root_interval_ind * root_duration
        note_durations.append(root_duration / elongation_factor)
        note_times.append(this_time)
        this_root_interval = time_between_roots[root_interval_ind]
    else:
        this_duration = root_duration / this_root_interval
        time_since_root += 1
        this_time += this_duration
        note_durations.append(this_duration)
        note_times.append(this_time)

seq_notes = [use_scale[x] for x in signature]
for i in xrange(len(seq_notes)):
    if seq_notes[i] >= 0 and seq_notes[i] <= 127:
        #        mf1.addNote(0,0,seq_notes[i],i*duration,duration*2,velocity)
        #        mf1.addNote(0,0,seq_notes[i],note_times[i],note_durations[i]*elongation_factor,velocity)
        mf1.addNote(0, 0, seq_notes[i], note_times[i], 0.25, velocity)

out_fname = fname_base + '_' + str(use_scale) + '.midi'
with open(out_fname, 'wb') as f:
    mf1.writeFile(f)
Exemple #22
0
track = 0
channel = 1 
pitch = 64 
time = 8 
duration = 1
volume = 100

MyMIDI.addNote(track,channel,pitch,time,duration,volume)

track = 0
channel = 2
pitch = 67 
time = 12 
duration = 1 
volume = 100

MyMIDI.addNote(track,channel,pitch,time,duration,volume)

track = 0
channel = 3
pitch = 72 
time = 16 
duration = 1 
volume = 100

MyMIDI.addNote(track,channel,pitch,time,duration,volume)


binfile = open("output.mid", 'wb') 
MyMIDI.writeFile(binfile) 
binfile.close()
    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.")
Exemple #24
0
class MIDITime(object):
    def __init__(self,
                 tempo=120,
                 outfile='miditime.mid',
                 seconds_per_year=5,
                 base_octave=5,
                 octave_range=1,
                 custom_epoch=None):
        self.tempo = tempo
        self.outfile = outfile
        self.tracks = []
        if custom_epoch:  # Only necessary if you have data that starts before 1970 and DO NOT want to start your midi at the first sound.
            self.epoch = custom_epoch
        else:
            self.epoch = datetime.datetime(1970, 1, 1)
        self.seconds_per_year = seconds_per_year
        self.base_octave = base_octave
        self.octave_range = octave_range
        self.note_chart = [["C"], ["C#", "Db"], ["D"], ["D#", "Eb"], ["E"],
                           ["F"], ["F#", "Gb"], ["G"], ["G#", "Ab"], ["A"],
                           ["A#", "Bb"], ["B"]]

    def beat(self, numdays):
        beats_per_second = self.tempo / 60.0
        beats_per_datayear = self.seconds_per_year * beats_per_second
        beats_per_dataday = beats_per_datayear / 365.25

        return round(beats_per_dataday * numdays, 2)

    def check_tz(self, input):
        if input.tzinfo:
            return input.tzinfo
        else:
            return None

    # Match the compare date to the timezone of whatever your input date is, if the input datetime is timezone-aware
    def normalize_datetime(self, input, compare_date):
        # if input is date, make epoch a date
        if type(input) is datetime.date:
            return compare_date.date()
        # # First, coerce to datetime in case it's a date
        # if type(input) is datetime.date:
        #     input = datetime.datetime.combine(input, datetime.datetime.min.time())

        # If tz data present, make epoch tz-aware
        tz = self.check_tz(input)
        if tz:
            return tz.localize(compare_date)
        else:
            return compare_date

    def days_since_epoch(self, input):
        normalized_epoch = self.normalize_datetime(input, self.epoch)
        return (input - normalized_epoch).total_seconds(
        ) / 60 / 60 / 24  # How many days, with fractions

    def map_week_to_day(self, year, week_num, desired_day_num=None):
        ''' Helper for weekly data, so when you jump to a new year you don't have notes playing too close together. Basically returns the first Sunday, Monday, etc. in 0-indexed integer format that is in that week.

        Usage: Once without a desired_day_num, then feed it a day_num in the loop

        Example:
        first_day = self.map_week_to_day(filtered_data[0]['Year'], filtered_data[0]['Week'])

        for r in filtered_data:
            # Convert the week to a date in that week
            week_start_date = self.map_week_to_day(r['Year'], r['Week'], first_day.weekday())
            # To get your date into an integer format, convert that date into the number of days since Jan. 1, 1970
            days_since_epoch = self.mymidi.days_since_epoch(week_start_date)

        '''
        year_start = datetime.datetime(int(year), 1, 1).date()
        year_start_day = year_start.weekday()
        week_start_date = year_start + datetime.timedelta(weeks=1 *
                                                          (int(week_num) - 1))
        week_start_day = week_start_date.weekday()
        if desired_day_num and week_start_day < desired_day_num:
            return week_start_date + datetime.timedelta(days=(desired_day_num -
                                                              week_start_day))
        return week_start_date

    def get_data_range(self, data_list, attribute_name, ignore_nulls=True):
        data_list = list(
            data_list
        )  # If the data is still a CSV object, once you loop through it you'll get rewind issues. So coercing to list.
        if ignore_nulls:
            minimum = min([
                float(d[attribute_name]) for d in data_list
                if d[attribute_name]
            ])
            maximum = max([
                float(d[attribute_name]) for d in data_list
                if d[attribute_name]
            ])
        else:
            minimum = min([float(d[attribute_name]) for d in data_list])
            maximum = max([float(d[attribute_name]) for d in data_list])
        return [minimum, maximum]

    def scale_to_note_classic(
        self, scale_pct, mode
    ):  # Only works in multi-octave mode if in C Major (i.e. all the notes are used. Should not be used in other keys, unless octave range is 1.)
        full_mode = []
        n = 0
        while n < self.octave_range:
            for m in mode:
                current_octave = str(self.base_octave + (n * 1))
                full_mode.append(m + current_octave)
            n += 1
        index = int(scale_pct * float(len(full_mode)))
        if index >= len(full_mode):
            index = len(full_mode) - 1
        print(full_mode[index])
        return full_mode[index]

    def scale_to_note(
        self, scale_pct, mode
    ):  # Manually go through notes so it doesn't inaccurately jump an octave sometimes.
        # First, write out a list of the possible notes for your octave range (i.e. all of the notes on the keyboard)
        full_c_haystack = []
        n = 0
        while n < self.octave_range:
            for note_group in self.note_chart:
                out_group = []
                for note in note_group:
                    current_octave = self.base_octave + (n * 1)
                    out_group.append(note + str(current_octave))
                full_c_haystack.append(out_group)
            n += 1

        full_mode = []
        n = 0
        while n < self.octave_range:
            for note in mode:
                note_found = False
                note_key = None
                for groupkey, group in enumerate(full_c_haystack):
                    for gnote in group:
                        if gnote[:-1] == note:
                            full_mode.append(gnote)
                            note_found = True
                            note_key = groupkey
                    if note_found:
                        break
                full_c_haystack = full_c_haystack[note_key:]
            n += 1

        # Now run through your specified mode and pick the exact notes in those octaves
        index = int(scale_pct * float(len(full_mode)))
        if index >= len(full_mode):
            index = len(full_mode) - 1

        return full_mode[index]

    def note_to_midi_pitch(self, notename):
        midinum = 0
        letter = notename[:-1]
        octave = notename[-1]

        i = 0
        for note in self.note_chart:
            for form in note:
                if letter == form:
                    midinum = i
                    break
            i += 1
        midinum += (int(octave)) * 12
        return midinum

    def linear_scale_pct(self, domain_min, domain_max, input, reverse=False):
        domain_range = float(domain_max) - float(domain_min)
        domain_pct = (input - domain_min) / domain_range

        if reverse:
            domain_pct = 1 - domain_pct
        return domain_pct

    def log_scale_pct(self,
                      domain_min,
                      domain_max,
                      input,
                      reverse=False,
                      direction='exponential'):
        if direction == 'exponential':  # E.G. earthquakes
            min_log_domain = pow(10, domain_min)
            max_log_domain = pow(10, domain_max)
            domain_range = max_log_domain - min_log_domain

            log_input = pow(10, input)
        elif direction == 'log':  # natural log scale
            if domain_min > 0:
                min_log_domain = log(domain_min)
            else:
                min_log_domain = log(
                    0.1
                )  # Technically this is not a true log scale. Someone smarter than me will have to figure this out.
            if domain_max > 0:
                max_log_domain = log(domain_max)
            else:
                max_log_domain = log(
                    0.1
                )  # Technically this is not a true log scale. Someone smarter than me will have to figure this out.
            domain_range = max_log_domain - min_log_domain

            log_input = log(input)

        domain_pct = (log_input - min_log_domain) / domain_range

        if reverse:
            domain_pct = 1 - domain_pct
        return domain_pct

    def scale(self, range_min, range_max, input_pct):
        scale_range = range_max - range_min
        return range_min + (input_pct * scale_range)

    def add_track(self, note_list):
        self.tracks.append(note_list)

    def add_note(self, track, channel, note):
        time = note[0]
        pitch = note[1]
        volume = note[2]
        duration = note[3]

        print(pitch, time, duration, volume)

        # Now add the note.
        self.MIDIFile.addNote(track, channel, pitch, time, duration, volume)

    def save_midi(self):
        # Create the MIDIFile Object with 1 track
        self.MIDIFile = MIDIFile(len(self.tracks))

        for i, note_list in enumerate(self.tracks):

            # Tracks are numbered from zero. Times are measured in beats.
            track = i
            time = 0

            # Add track name and tempo.
            self.MIDIFile.addTrackName(track, time, "Track 1")
            self.MIDIFile.addTempo(track, time, self.tempo)

            for n in note_list:
                if len(n) == 2:
                    note = n[0]
                    channel = n[1]
                else:
                    note = n
                    channel = 0
                self.add_note(track, channel, note)

        # And write it to disk.
        binfile = open(self.outfile, 'wb')
        self.MIDIFile.writeFile(binfile)
        binfile.close()
def create_midi_from_progression(progression):
    """
	Given a chord progression in the form of a list of chord instances,
	creates a MIDI file as an output.
	"""
    MyMIDI = MIDIFile(4)
    track = 0
    time = 0
    MyMIDI.addTrackName(track, time, "Soprano")
    MyMIDI.addTempo(track, time, 60)
    track += 1
    MyMIDI.addTrackName(track, time, "Alto")
    MyMIDI.addTempo(track, time, 60)
    track += 1
    MyMIDI.addTrackName(track, time, "Tenor")
    MyMIDI.addTempo(track, time, 60)
    track += 1
    MyMIDI.addTrackName(track, time, "Bass")
    MyMIDI.addTempo(track, time, 60)

    channel = 0
    duration = 1
    volume = 100

    for index, chord in enumerate(progression):
        track = 3
        for note in chord.get_notes():
            pitch = note.get_midi_number()
            MyMIDI.addNote(track, channel, pitch, time, duration, volume)
            track -= 1
        time += 1
        if index == len(progression) - 2:
            duration = 2
    binfile = open("output_individual_voices.mid", 'wb')
    MyMIDI.writeFile(binfile)
    binfile.close()

    MyMIDI = MIDIFile(2)
    track = 0
    time = 0
    MyMIDI.addTrackName(track, time, "Upper Voices")
    MyMIDI.addTempo(track, time, 60)
    track += 1
    MyMIDI.addTrackName(track, time, "Lower Voices")
    MyMIDI.addTempo(track, time, 60)

    duration = 1

    for index, chord in enumerate(progression):
        track = 1
        count = 0
        for note in chord.get_notes():
            pitch = note.get_midi_number()
            MyMIDI.addNote(track, channel, pitch, time, duration, volume)
            if count % 2 == 1:
                track -= 1
            count += 1
        time += 1
        if index == len(progression) - 2:
            duration = 2
    binfile = open("output_two_hands.mid", 'wb')
    MyMIDI.writeFile(binfile)
    binfile.close()
Exemple #26
0
class MIDITime(object):

    def __init__(self, tempo=120, outfile='miditime.mid', seconds_per_year=5, base_octave=5, octave_range=1, custom_epoch=None):
        self.tempo = tempo
        self.outfile = outfile
        self.tracks = []
        if custom_epoch:  # Only necessary if you have data that starts before 1970 and DO NOT want to start your midi at the first sound.
            self.epoch = custom_epoch
        else:
            self.epoch = datetime.datetime(1970, 1, 1)
        self.seconds_per_year = seconds_per_year
        self.base_octave = base_octave
        self.octave_range = octave_range
        self.note_chart = [["C"], ["C#", "Db"], ["D"], ["D#", "Eb"], ["E"], ["F"], ["F#", "Gb"], ["G"], ["G#", "Ab"], ["A"], ["A#", "Bb"], ["B"]]

    def beat(self, numdays):
        beats_per_second = self.tempo / 60.0
        beats_per_datayear = self.seconds_per_year * beats_per_second
        beats_per_dataday = beats_per_datayear / 365.25

        return round(beats_per_dataday * numdays, 2)

    def check_tz(self, input):
        if input.tzinfo:
            return input.tzinfo
        else:
            return None

    # Match the compare date to the timezone of whatever your input date is, if the input datetime is timezone-aware
    def normalize_datetime(self, input, compare_date):
        # if input is date, make epoch a date
        if type(input) is datetime.date:
            return compare_date.date()
        # # First, coerce to datetime in case it's a date
        # if type(input) is datetime.date:
        #     input = datetime.datetime.combine(input, datetime.datetime.min.time())

        # If tz data present, make epoch tz-aware
        tz = self.check_tz(input)
        if tz:
            return tz.localize(compare_date)
        else:
            return compare_date

    def days_since_epoch(self, input):
        normalized_epoch = self.normalize_datetime(input, self.epoch)
        return (input - normalized_epoch).total_seconds() / 60 / 60 / 24  # How many days, with fractions

    def map_week_to_day(self, year, week_num, desired_day_num=None):
        ''' Helper for weekly data, so when you jump to a new year you don't have notes playing too close together. Basically returns the first Sunday, Monday, etc. in 0-indexed integer format that is in that week.

        Usage: Once without a desired_day_num, then feed it a day_num in the loop

        Example:
        first_day = self.map_week_to_day(filtered_data[0]['Year'], filtered_data[0]['Week'])

        for r in filtered_data:
            # Convert the week to a date in that week
            week_start_date = self.map_week_to_day(r['Year'], r['Week'], first_day.weekday())
            # To get your date into an integer format, convert that date into the number of days since Jan. 1, 1970
            days_since_epoch = self.mymidi.days_since_epoch(week_start_date)

        '''
        year_start = datetime.datetime(int(year), 1, 1).date()
        year_start_day = year_start.weekday()
        week_start_date = year_start + datetime.timedelta(weeks=1 * (int(week_num) - 1))
        week_start_day = week_start_date.weekday()
        if desired_day_num and week_start_day < desired_day_num:
            return week_start_date + datetime.timedelta(days=(desired_day_num - week_start_day))
        return week_start_date

    def get_data_range(self, data_list, attribute_name, ignore_nulls=True):
        data_list = list(data_list)  # If the data is still a CSV object, once you loop through it you'll get rewind issues. So coercing to list.
        if ignore_nulls:
            minimum = min([float(d[attribute_name]) for d in data_list if d[attribute_name]])
            maximum = max([float(d[attribute_name]) for d in data_list if d[attribute_name]])
        else:
            minimum = min([float(d[attribute_name]) for d in data_list])
            maximum = max([float(d[attribute_name]) for d in data_list])
        return [minimum, maximum]

    def scale_to_note_classic(self, scale_pct, mode):  # Only works in multi-octave mode if in C Major (i.e. all the notes are used. Should not be used in other keys, unless octave range is 1.)
        full_mode = []
        n = 0
        while n < self.octave_range:
            for m in mode:
                current_octave = str(self.base_octave + (n * 1))
                full_mode.append(m + current_octave)
            n += 1
        index = int(scale_pct * float(len(full_mode)))
        if index >= len(full_mode):
            index = len(full_mode) - 1
        print(full_mode[index])
        return full_mode[index]

    def scale_to_note(self, scale_pct, mode):  # Manually go through notes so it doesn't inaccurately jump an octave sometimes.
        # First, write out a list of the possible notes for your octave range (i.e. all of the notes on the keyboard)
        full_c_haystack = []
        n = 0
        while n < self.octave_range:
            for note_group in self.note_chart:
                out_group = []
                for note in note_group:
                    current_octave = self.base_octave + (n * 1)
                    out_group.append(note + str(current_octave))
                full_c_haystack.append(out_group)
            n += 1

        full_mode = []
        n = 0
        while n < self.octave_range:
            for note in mode:
                note_found = False
                note_key = None
                for groupkey, group in enumerate(full_c_haystack):
                    for gnote in group:
                        if gnote[:-1] == note:
                            full_mode.append(gnote)
                            note_found = True
                            note_key = groupkey
                    if note_found:
                        break
                full_c_haystack = full_c_haystack[note_key:]
            n += 1

        # Now run through your specified mode and pick the exact notes in those octaves
        index = int(scale_pct * float(len(full_mode)))
        if index >= len(full_mode):
            index = len(full_mode) - 1

        return full_mode[index]

    def note_to_midi_pitch(self, notename):
        midinum = 0
        letter = notename[:-1]
        octave = notename[-1]

        i = 0
        for note in self.note_chart:
            for form in note:
                if letter == form:
                    midinum = i
                    break
            i += 1
        midinum += (int(octave)) * 12
        return midinum

    def linear_scale_pct(self, domain_min, domain_max, input, reverse=False):
        domain_range = float(domain_max) - float(domain_min)
        domain_pct = (input - domain_min) / domain_range

        if reverse:
            domain_pct = 1 - domain_pct
        return domain_pct

    def log_scale_pct(self, domain_min, domain_max, input, reverse=False, direction='exponential'):
        if direction == 'exponential':  # E.G. earthquakes
            min_log_domain = pow(10, domain_min)
            max_log_domain = pow(10, domain_max)
            domain_range = max_log_domain - min_log_domain

            log_input = pow(10, input)
        elif direction == 'log':  # natural log scale
            if domain_min > 0:
                min_log_domain = log(domain_min)
            else:
                min_log_domain = log(0.1)  # Technically this is not a true log scale. Someone smarter than me will have to figure this out.
            if domain_max > 0:
                max_log_domain = log(domain_max)
            else:
                max_log_domain = log(0.1)  # Technically this is not a true log scale. Someone smarter than me will have to figure this out.
            domain_range = max_log_domain - min_log_domain

            log_input = log(input)

        domain_pct = (log_input - min_log_domain) / domain_range

        if reverse:
            domain_pct = 1 - domain_pct
        return domain_pct

    def scale(self, range_min, range_max, input_pct):
        scale_range = range_max - range_min
        return range_min + (input_pct * scale_range)

    def add_track(self, note_list):
        self.tracks.append(note_list)

    def add_note(self, track, channel, note):
        time = note[0]
        pitch = note[1]
        volume = note[2]
        duration = note[3]

        print(pitch, time, duration, volume)

        # Now add the note.
        self.MIDIFile.addNote(track, channel, pitch, time, duration, volume)

    def save_midi(self):
        # Create the MIDIFile Object with 1 track
        self.MIDIFile = MIDIFile(len(self.tracks))

        for i, note_list in enumerate(self.tracks):

            # Tracks are numbered from zero. Times are measured in beats.
            track = i
            time = 0

            # Add track name and tempo.
            self.MIDIFile.addTrackName(track, time, "Track 1")
            self.MIDIFile.addTempo(track, time, self.tempo)

            for n in note_list:
                if len(n) == 2:
                    note = n[0]
                    channel = n[1]
                else:
                    note = n
                    channel = 0
                self.add_note(track, channel, note)

        # And write it to disk.
        binfile = open(self.outfile, 'wb')
        self.MIDIFile.writeFile(binfile)
        binfile.close()
Exemple #27
0
def image_process_2():
    image = cv2.imread('temp/src_image.jpg', 0)
    list_ = image.tolist()
    if max(map(max, list_)) > 225:
        thresh_1 = 0.66 * max(map(max, list_))
        thresh_2 = 0.70 * max(map(max, list_))
        thresh_3 = 0.72 * max(map(max, list_))
    elif max(map(max, list_)) < 200:
        thresh_1 = 0.65 * max(map(max, list_))
        thresh_2 = 0.75 * max(map(max, list_))
        thresh_3 = 0.84 * max(map(max, list_))
    else:
        thresh_1 = 0.66 * max(map(max, list_))
        thresh_2 = 0.72 * max(map(max, list_))
        thresh_3 = 0.75 * max(map(max, list_))

    ret, img_gray1 = cv2.threshold(dstImg, thresh_1, 255, cv2.THRESH_BINARY)
    ret, img_gray2 = cv2.threshold(dstImg, thresh_2, 255, cv2.THRESH_BINARY)
    ret, img_gray3 = cv2.threshold(dstImg, thresh_3, 255, cv2.THRESH_BINARY)

    img_gray = 255 * np.ones(shape=[780, 551], dtype=np.uint8)

    # cv2.namedWindow("img_gray", cv2.WINDOW_AUTOSIZE)
    # cv2.imshow("img_gray", img_gray)

    for i in range(780):
        for j in range(551):
            if img_gray1[i][j] == 0 and img_gray2[i][j] == 0 and img_gray3[i][
                    j] == 0:
                img_gray[i][j] = 0
            elif img_gray1[i][j] == 0 or img_gray2[i][j] == 0:
                if img_gray3[i][j] == 0:
                    img_gray[i][j] = 0
            elif img_gray1[i][j] == 0 or img_gray3[i][j] == 0:
                if img_gray2[i][j] == 0:
                    img_gray[i][j] = 0
            elif img_gray2[i][j] == 0 or img_gray3[i][j] == 0:
                if img_gray1[i][j] == 0:
                    img_gray[i][j] = 0

    img = img_gray

    # height, width = img.shape[:2]
    # img_width, img_height = img_gray.shape[::-1]

    # <<找五線譜
    staff_recs = locate_images(img_gray, staff_imgs, staff_lower, staff_upper,
                               staff_thresh)
    staff_recs = [j for i in staff_recs for j in i]
    heights = [r.y for r in staff_recs] + [0]
    histo = [heights.count(i) for i in range(0, max(heights) + 1)]
    avg = np.mean(list(set(histo)))
    staff_recs = [r for r in staff_recs if histo[r.y] > avg]
    staff_recs = merge_recs(staff_recs, 0.01)
    # staff_recs_img = img.copy()
    # for r in staff_recs:
    #     r.draw(staff_recs_img, (0, 0, 255), 2)
    # >>

    #  <<找五線譜的模板
    resul = []
    resul.append(staff_recs[0])
    for index, item in enumerate(staff_recs):
        if abs(resul[-1].y - item.y) > 100:
            resul.append(item)
        else:
            continue
    # print("resul", resul)
    # >>

    # <<找五線譜的y座標
    staff = []
    line_axis = []
    for item in resul:
        # print("item.y", item.y)
        line_axis.append(item.y)
        y_project = []
        line_ = []
        for i in range(int(item.h)):
            count = 0
            for j in range(int(item.w)):
                if img[item.y + i, item.x + j] == 0:
                    count += 1
                else:
                    continue
            y_project.append(count)
        # print("y_project(count)", y_project)

        i = 1
        while i < len(y_project):
            if (y_project[i] == 0):
                i += 1
                continue
            elif (y_project[i] > 0 and y_project[i + 1] > 0
                  and y_project[i + 2] > 0):
                line = (i + i + 1 + i + 2) // 3
                line_.append(line + item.y)
                i += 3
            elif (y_project[i] > 0 and y_project[i + 1] > 0):
                line = (i + i + 1) // 2
                line_.append(line + item.y)
                i += 2
            else:
                line = i
                line_.append(line + item.y)
                i += 1
                continue
        staff.append(line_)
    # print("line_axis", line_axis)   #每行譜的五條線的最上面那條
    # print("staff", staff)   #每行譜的五條線
    # >>

    ##### 第一行對x投影
    x_range = [102] * (len(resul))
    x_range[0] = 120
    # print('ra_list',ra_list)
    quarter_recs = []
    half_recs = []
    for x_range_index, x_range_ in enumerate(x_range):
        x_project1 = []
        for x in range(x_range_, 485):
            count = 0
            for y in range(staff[x_range_index][0] - 15,
                           staff[x_range_index][4] + 15):
                if img[y, x] == 0:
                    count += 1
                else:
                    continue
            x_project1.append(count)

        # <<音符的x範圍
        note_xposition = []
        one_note = []
        next_to = False
        for index, item in enumerate(x_project1):
            if item > 8 and next_to == False:  #找到第一個大於9的x
                one_note.append(index)
                next_to = True  #觸發next_to等於True
            elif item > 8 and next_to == True:  #next_to等於True的情況下如果還是大於九則不做理會
                continue
            elif item < 8 and next_to == True:  #next_to等於True的情況下如果小於九則存入one_note
                one_note.append(index - 1)
                if one_note[1] - one_note[
                        0] > 5:  #one_note[0]是起始x,one_note[1]是結束的x,間距要超過5才會把它存入note_xposition
                    # print("index" ,index)
                    note_xposition.append(one_note)
                one_note = []
                next_to = False  #next_to等於False
        # print("note_xposition", note_xposition)
        # print('xpo', time.time() - start_time)
        # 音符的x範圍>>

        # <<音符的y範圍
        note_yposition = []
        note_xpos_yproject = []
        # for index__ in note_xposition:
        # note_xpos_yproject = []
        for r in range(len(note_xposition)):
            for j in range(staff[x_range_index][0] - 15,
                           staff[x_range_index][4] + 15):
                count = 0
                for i in range(note_xposition[r][0] + x_range_,
                               note_xposition[r][1] + x_range_):
                    if img[j, i] == 0:
                        count += 1
                    else:
                        continue
                note_xpos_yproject.append(count)

            one_note_ = []
            next_to_ = False
            for index_, item in enumerate(note_xpos_yproject):
                if item > 3 and next_to_ == False:  #找到第一個大於3的y
                    one_note_.append(index_)
                    next_to_ = True  #觸發next_to_等於True
                elif item > 3 and next_to_ == True:  #next_to_等於True的情況下如果還是大於3則不做理會
                    continue
                elif item < 3 and next_to_ == True:  #next_to_等於True的情況下如果小於3則存入one_note_
                    one_note_.append(index_ - 1)
                    if one_note_[1] - one_note_[
                            0] > 6:  #one_note_[0]是起始y,one_noteY[1]是結束的y,間距要超過6才會把它存入note_xposition
                        note_yposition.append(one_note_)
                    one_note_ = []
                    next_to_ = False  #next_to等於False
            # print("note_xpos_yproject", note_xpos_yproject)
            note_xpos_yproject = []
        # print("note_yposition", note_yposition)
        # 音符的y範圍>>

        # fingers = []
        # for i in range(len(note_xposition)):
        #     crop_img = img[staff[x_range_index][4]+15 : staff[x_range_index][4]+30, x_range[x_range_index] + note_xposition[i][0] : x_range[x_range_index] + note_xposition[i][1]]
        #     if i == 1:
        #         print("crop_img", crop_img)
        #     # 找finger1
        #     finger1_recs = locate_images(crop_img, finger1_imgs, finger1_lower, finger1_upper, finger1_thresh)

        #     # finger1_recs = finger1_recs[0]
        #     finger1_recs = merge_recs([j for i in finger1_recs for j in i], 0.5)
        #     finger1_recs_img = img.copy()
        #     if i == 1:
        #         print("finger1_recs", len(finger1_recs))
        #     for r in finger1_recs:
        #         r.draw(finger1_recs_img, (0, 0, 255), 2)
        # cv2.imwrite('finger1_recs_img.png', finger1_recs_img)
        # open_file('finger1_recs_img.png')

        global recs
        recs = []
        for r in range(len(note_xposition)):
            count = 0
            for j in range(staff[x_range_index][0] - 15 + note_yposition[r][0],
                           staff[x_range_index][0] - 15 +
                           note_yposition[r][1]):
                for i in range(note_xposition[r][0] + x_range_,
                               note_xposition[r][1] + x_range_):
                    if img[j, i] == 0:
                        count += 1
                    else:
                        continue
            # print(count/((note_xposition[r][1]-note_xposition[r][0])*(note_yposition[r][1]-note_yposition[r][0])))
            if (count /
                ((note_xposition[r][1] - note_xposition[r][0]) *
                 (note_yposition[r][1] - note_yposition[r][0])) > 0.64):
                rec = Rectangle(
                    note_xposition[r][0] + x_range_,
                    staff[x_range_index][0] - 15 + note_yposition[r][0],
                    note_xposition[r][1] - note_xposition[r][0],
                    note_yposition[r][1] - note_yposition[r][0])
                quarter_recs.append(rec)
                recs.append(rec)
            elif (count /
                  ((note_xposition[r][1] - note_xposition[r][0]) *
                   (note_yposition[r][1] - note_yposition[r][0])) <= 0.64):
                rec = Rectangle(
                    note_xposition[r][0] + x_range_,
                    staff[x_range_index][0] - 15 + note_yposition[r][0],
                    note_xposition[r][1] - note_xposition[r][0],
                    note_yposition[r][1] - note_yposition[r][0])
                half_recs.append(rec)
                recs.append(rec)

    # print("quarter_recs", quarter_recs)
    # print("half_recs", half_recs)
    # print("quarter_recs", len(quarter_recs))
    # print("half_recs", len(half_recs))
    l = recs
    # print("rec", rec)
    with open("temp/output.txt", "wb") as fp:  #Pickling
        pickle.dump(l, fp)

    # with open("test.txt", "rb") as fp:   # Unpickling
    #     b = pickle.load(fp)

    staff_boxes = [
        Rectangle(x_range[r], staff[r][2] - 33, 485 - x_range[r], 68)
        for r in range(len(staff))
    ]
    # staff_boxes_img = img.copy()
    # for r in staff_boxes:
    #     r.draw(staff_boxes_img, (0, 0, 255), 2)
    # cv2.imwrite('staff_boxes_img.png', staff_boxes_img)
    # open_file('staff_boxes_img.png')

    # objects_img = staff_boxes_img

    # 畫四分音符
    # quarter_recs_img = img.copy()
    # for r in quarter_recs:
    #     r.draw(quarter_recs_img, (0, 0, 255), 2)
    # cv2.imwrite('quarter_recs_img.png', quarter_recs_img)
    # open_file('quarter_recs_img.png')

    # 畫二分音符
    # half_recs_img = img.copy()
    # for r in half_recs:
    #     r.draw(half_recs_img, (0, 0, 255), 2)
    # cv2.imwrite('half_recs_img.png', half_recs_img)
    # open_file('half_recs_img.png')

    staff_notes = []
    note_groups = []
    for box in staff_boxes:
        staff_sharps = []
        staff_flats = []
        quarter_notes = [
            Note(r, "4,8", box, staff_sharps, staff_flats)
            for r in quarter_recs
            if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0
        ]
        half_notes = [
            Note(r, "2", box, staff_sharps, staff_flats) for r in half_recs
            if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0
        ]

        staff_notes = quarter_notes + half_notes

        staff_notes.sort(key=lambda n: n.rec.x)
        staffs = [r for r in staff_recs if r.overlap(box) > 0]
        staffs.sort(key=lambda r: r.x)
        note_color = (randint(0, 255), randint(0, 255), randint(0, 255))
        note_group = []
        i = 0
        j = 0
        while (i < len(staff_notes)):
            if j < len(staffs):
                if staff_notes[i].rec.x > staffs[j].x:
                    r = staffs[j]
                    j += 1
                    if len(note_group) > 0:
                        note_groups.append(note_group)
                        note_group = []
                    note_color = (randint(0,
                                          255), randint(0,
                                                        255), randint(0, 255))
                else:
                    note_group.append(staff_notes[i])
                    # staff_notes[i].rec.draww(img, note_color, 2)
                    i += 1
            else:
                note_group.append(staff_notes[i])
                # staff_notes[i].rec.draww(img, note_color, 2)
                i += 1
        note_groups.append(note_group)

    # for r in staff_boxes:
    #     r.draw(img, (0, 0, 255), 2)

    # cv2.imwrite('res.png', img)
    # open_file('res.png')

    # for note_group in note_groups:
    #     print([ note.note + " " + note.sym for note in note_group])

    midi = MIDIFile(1)

    track = 0
    time = 0
    channel = 0
    volume = 100

    midi.addTrackName(track, time, "Track")
    midi.addTempo(track, time, 60)

    for note_group in note_groups:
        duration = None
        for note in note_group:
            note_type = note.sym
            if note_type == "1":
                duration = 4
            elif note_type == "2":
                duration = 2
            elif note_type == "4,8":
                # duration = 1 if len(note_group) == 1 else 0.5
                duration = 1
            pitch = note.pitch
            midi.addNote(track, channel, pitch, time, duration, volume)
            time += duration

    # And write it to disk.
    binfile = open("temp/output.mid", 'wb')
    midi.writeFile(binfile)
    binfile.close()
Exemple #28
0
    midi = MIDIFile(1)
     
    track = 0   
    time = 0
    channel = 0
    volume = 100
    
    midi.addTrackName(track, time, "Track")
    midi.addTempo(track, time, 140)

    for note_group in note_groups:
        duration = None
        for note in note_group:
            note_type = note.sym
            if note_type == "1":
                duration = 4
            elif note_type == "2":
                duration = 2
            elif note_type == "4,8":
                duration = 1 if len(note_group) == 1 else 0.5
            pitch = note.pitch
            midi.addNote(track,channel,pitch,time,duration,volume)
            time += duration
            midi.addNote(track,channel,pitch,time,4,0)

    # And write it to disk.
    binfile = open("output.mid", 'wb')
    midi.writeFile(binfile)
    binfile.close()
    ('output.mid')
    def play(self):
        ''' Play Method
                Generates the MIDI tracks necessary to play the composition
                Plays the composition using pygame module
        '''
        # Create two MIDI tracks
        midi = MIDIFile(2)
        # Piano right hand track
        track = 0
        time = 0
        midi.addTrackName(track, time, "Piano Right Hand")
        midi.addTempo(track, time, self.tempo)
        track = 1
        midi.addTrackName(track, time, "Piano Left Hand")
        midi.addTempo(track, time, self.tempo)
        while (self.boolean):
            # Create new progressions as long as self.boolean is True
            progression = self.progressionf()
            proglength = len(progression)
            flag = 0
            # If the length of the progression is greater than self.totalbeats,
            # the composition will last longer than the user-input duration
            # Therefore, try 10 more times to generate a progression shorter
            # than self.totalbeats.
            while self.totalbeats <= proglength:
                progression = self.progressionf()
                proglength = len(progression)
                flag += 1
                if flag == 10:
                    break
            # If the length of the progression is suitable, add it to self.compprog
            if self.totalbeats >= proglength:
                self.compprog.extend(progression)
                # Subtract length of progression from self.totalbeats (so that
                # self.totalbeats keeps track of number of beats left in the
                # composition)
                self.totalbeats -= proglength
                track = 0
                channel = 0
                volume = 100
                # Create rhythmlist
                temprlist = self.rhythmgen(progression)
                rhythmlist = []
                for r in temprlist:
                    for el in r:
                        rhythmlist.append(el)
                # Create melodylist using rhythmlist
                melodylist = self.melodygen(progression, temprlist, self.scale,
                                            5)
                rllength = len(rhythmlist)
                # Add each note to the piano right hand track
                for n in range(rllength):
                    pitch = melodylist[n]
                    duration = rhythmlist[n]
                    midi.addNote(track, channel, pitch, self.time1, duration,
                                 volume)
                    self.time1 += rhythmlist[n]
            # If program fails to generate a progression shorter than self.totalbeats,
            # add the tonic to self.compprog and end the composition
            else:
                self.compprog.append(self.tonic)
                self.boolean = False
        # Piano left hand track
        track = 1
        channel = 0
        duration = 0.25
        volume = 80
        # For every harmony in self.compprog, add the alberti bass line
        for n in range(len(self.compprog)):
            a = self.albertibass(
                harmony(self.compprog[n], self.roots, self.reverse_labels), 4)
            if n == len(self.compprog) - 1:
                pitch = a[0]
                duration = 0.5
                midi.addNote(track, channel, pitch, self.time2, duration,
                             volume)
            else:
                for iter in range(2):
                    for tone in range(4):
                        pitch = a[tone]
                        midi.addNote(track, channel, pitch, self.time2,
                                     duration, volume)
                        self.time2 += 0.25
        # Write a midi file
        file = "composition.mid"
        with open(file, 'wb') as binfile:
            midi.writeFile(binfile)
        # Play the midi file using pygame
        pygame.init()
        pygame.mixer.init()
        pygame.mixer.music.load(file)
        pygame.mixer.music.play()

        while pygame.mixer.music.get_busy():
            pygame.time.Clock().tick(10)
def create_midi_from_progression(progression):
	"""
	Given a chord progression in the form of a list of chord instances,
	creates a MIDI file as an output.
	"""
	MyMIDI = MIDIFile(4)
	track = 0
	time = 0
	MyMIDI.addTrackName(track, time, "Soprano")
	MyMIDI.addTempo(track, time, 60)
	track += 1
	MyMIDI.addTrackName(track, time, "Alto")
	MyMIDI.addTempo(track, time, 60)
	track += 1
	MyMIDI.addTrackName(track, time, "Tenor")
	MyMIDI.addTempo(track, time, 60)
	track += 1
	MyMIDI.addTrackName(track, time, "Bass")
	MyMIDI.addTempo(track, time, 60)

	channel = 0
	duration = 1
	volume = 100

	for index, chord in enumerate(progression):
		track = 3
		for note in chord.get_notes():
			pitch = note.get_midi_number()
			MyMIDI.addNote(track, channel, pitch, time, duration, volume)
			track -= 1
		time += 1
		if index == len(progression) - 2:
			duration = 2
	binfile = open("output_individual_voices.mid", 'wb')
	MyMIDI.writeFile(binfile)
	binfile.close()


	MyMIDI = MIDIFile(2)
	track = 0
	time = 0
	MyMIDI.addTrackName(track, time, "Upper Voices")
	MyMIDI.addTempo(track, time, 60)
	track += 1
	MyMIDI.addTrackName(track, time, "Lower Voices")
	MyMIDI.addTempo(track, time, 60)

	duration = 1

	for index, chord in enumerate(progression):
		track = 1
		count = 0
		for note in chord.get_notes():
			pitch = note.get_midi_number()
			MyMIDI.addNote(track, channel, pitch, time, duration, volume)
			if count % 2 == 1:
				track -= 1
			count += 1
		time += 1
		if index == len(progression) - 2:
			duration = 2
	binfile = open("output_two_hands.mid", 'wb')
	MyMIDI.writeFile(binfile)
	binfile.close()
Exemple #31
0
volume = 100
time = time + 2
MyMIDI.addNote(track1, channel, pitch1, time, duration, volume)
#time = time +1
MyMIDI.addNote(track2, channel2, pitch2, time, duration, volume)
time = time + 2
MyMIDI.addNote(track1, channel, pitch1, time, duration, volume)
#time = time +1
MyMIDI.addNote(track2, channel2, pitch2, time, duration, volume)
time = time + 2
MyMIDI.addNote(track1, channel, pitch1, time, duration, volume)
#time = time +1
MyMIDI.addNote(track2, channel2, pitch2, time, duration, volume)
MyMIDI.addNote(track2, channel2, 67, time, duration, volume)
#print(row[1])
# Create the MIDIFile Object
# Now add the note.

#MyMIDI.addNote(track,channel,55,time,duration,volume)
#MyMIDI.addNote(track,channel,76,4,duration,volume)
#MyMIDI.addNote(track,channel,80,6,duration,volume)
# Add track name and tempo. The first argument to addTrackName and
# addTempo is the time to write the event.

# Add a note. addNote expects the following information:

# And write it to disk.
binfile = open("chordTemp.mid", 'wb')
MyMIDI.writeFile(binfile)
binfile.close()
Exemple #32
0
class MidiCreator(object):
    def __init__(self, config_file_name):
        """Convert data in a CSV file to a MIDI file."""
        # load instrument names and MIDI note ranges from config file
        self._config = configparser.ConfigParser()
        self._config.read(config_file_name)
        # Create the MIDIFile object with 1 track
        self._midi = MIDIFile(1)
        # Add track name and tempo.
        self._midi.addTrackName(
            0,  # track number
            0,  # time
            self._config.get('midi',
                             'track name',
                             fallback=DEFAULT_TRACK_NAME))
        self._midi.addTempo(
            0,  # track number
            0,  # time
            int(self._config.get('midi',
                                 'tempo',
                                 fallback=DEFAULT_TEMPO)))

    def _init_note_makers(self, csv_file_name):
        """Create a list of NoteMaker objects, one for each csv column that is
        mapped to an instrument by the config file."""
        self._note_makers = []
        csv_file = open(csv_file_name)
        # first line of csv file must have column names
        columns = csv_file.readline().strip().split(',')
        # Create one notemaker instance for every csv column that we'll be
        # using to produce music. Each notemaker is assigned to a separate
        # channel, since each instrument must have its own channel.
        channel = 0
        for column_index, column_name in enumerate(columns):
            if NoteMaker.is_musical_column(column_name, self._config):
                if self._config['columns'][column_name]:
                    self._note_makers.append(
                        NoteMaker(column_name, column_index, self._midi,
                                  self._config, channel))
                channel += 1
            if channel > 15:
                print("Warning: more than 16 channels, ignoring excess.")
                break
        # Now each notemaker object needs to know the maximum value for its
        # data column, so that it can be scaled to fit the range of the
        # instrument assigned to that column.
        for line in csv_file:
            split_line = line.strip().split(',')
            for note_maker in self._note_makers:
                note_maker.test_for_max(split_line)

    def write_midi_file(self, csv_file_name, midi_file_name):
        # Create a list of pitchmaker objects, one for each column that will be
        # used to produce music.
        self._init_note_makers(csv_file_name)
        # Write notes to the midi file
        csv_file = open(csv_file_name)
        csv_file.readline()  # skip header
        for line in csv_file:
            split_line = line.strip().split(',')
            for note_maker in self._note_makers:
                note_maker.add_note(split_line)
        # write the midi data to disk
        with open(midi_file_name, 'wb') as midi_file:
            self._midi.writeFile(midi_file)