def __init__(self, tempo, key, num_measures, instruments, singers, num_tracks): self.num_tracks = num_tracks self.num_measures = num_measures self.MyMIDI = MIDIFile(self.num_tracks + 1) self.instruments = instruments self.singers = singers self.key = key self.time = 0 self.sections = [] # stores the order of song sections. E.g. Chorus, Verse, Bridge self.MyMIDI.addTempo(track=0, tempo=tempo, time=0) self.triads = self.create_triad_sequence(num_measures, key) self.notes_for_track = [[]] # creates the list of notes for each track # sets the unique track and channel number for each singer for x in range(self.num_tracks//3): for singer_index in range(len(self.singers[x])): if self.num_tracks//3*singer_index + x >= 9: # skips over track 10, which is reserved for percussion instruments only self.singers[x][singer_index].track = self.num_tracks//3*singer_index + x + 1 self.singers[x][singer_index].channel = self.num_tracks//3*singer_index + x + 1 else: self.singers[x][singer_index].track = self.num_tracks//3*singer_index + x self.singers[x][singer_index].channel = self.num_tracks//3*singer_index + x # creates the tracks for each singer for singer in [row[0] for row in self.singers]: self.add_track(singer) for singer in [row[1] for row in self.singers]: self.add_track(singer) for singer in [row[2] for row in self.singers]: self.add_track(singer) self.build_song()
def write_to_midi(composition, comp_name, tempo=120): MyMIDI = MIDIFile(1) track = 0 time = 0 channel = 0 MyMIDI.addTrackName(track, time, "Composition") MyMIDI.addTempo(track, time, tempo) for note in composition: if note.value != 'silence': MyMIDI.addNote(track, channel, convert_pitch_to_MIDI(note.value, note.octave), note.start_time, note.duration, note.volume) binfile = open(comp_name + ".mid", 'wb') MyMIDI.writeFile(binfile) binfile.close()
def __init__(self): # these values are all entered by the user via the GUI self.TimeSig = None # get the time signature self.Key = None # on which key should the music be written? gathered from user self.Form = None # for later use if we try to write certain forms of music (Sonata, Concerto, Ritornello, etc.) self.Genre = None # for later use if we try to include playing techniques related to certain genre (add syncopations for Jazz, etc) self.flavor = None self.instrs = dict([('piano', 0), ('harpsichord', 6), ('glock', 9), ('vibes', 11), ('marimba', 12), ('organ', 19), ('guitar', 24), ('bass', 32), ('violin', 40), ('viola', 41), ('cello', 42), ('contrabass', 43), ('harp', 46), ('timps', 47), ('voice', 54), ('trumpet', 56), ('tuba', 58), ('horn', 60), ('alto sax', 65), ('oboe', 68), ('bassoon', 70), ('clarinet', 71), ('flute', 73), ('recorder', 74), ('bottle', 75), ('whistle', 78), ('fifths', 96), ('halo', 94), ('goblins', 101), ('koto', 107), ('bagpipe', 109), ('taiko', 116), ('toms', 117), ('breath', 121), ('seashore', 122), ('bird', 123), ('phone', 124), ('applause', 126)]) # dictionary of possible instruments, linking the string name of the instrument to its number so that it can be accessed in the Midi file self.MyMIDI = MIDIFile(1) self.tracks = (0, 1) self.channels = (0, 1, 2, 3) # four channels, (one for Soprano, Alto, Tenor, Bass) self.length = 20 # 20 as the default number of measures
''' Created on Jul 30, 2013 modified from the single-class_note-example form midiutil @author: bailey ''' ############################################################################ # A sample program to create a multi-track MIDI file, add notes, # and write to disk. ############################################################################ #Import the library from MidiFile3 import MIDIFile # Create the MIDIFile Object MyMIDI = MIDIFile(2) ### the integer = the number of parallel tracks available # Add track names and tempo. The first argument to addTrackName and # addTempo is the time to write the event. This initialises the tracks. tracks = (0, 1) start_time = 0 MyMIDI.addTrackName(tracks[0],start_time,"Piano") MyMIDI.addTempo(tracks[0],start_time, 120) #MyMIDI.addTrackName(tracks[1],start_time,"Cello") #MyMIDI.addTempo(tracks[1],start_time, 120) # Each track can hold multiple channels, we'll use two for now channels = (0,1) # Add a class_note. addNote expects the following information: #channel = some integer >= 0
8 : ("b3", 59), 9 : ("a3", 57), 10 : ("g3", 55), 11 : ("f3", 53), 12 : ("e3", 52), 13 : ("d3", 50), 14 : ("c3", 48), 15 : ("b2", 47), 16 : ("a2", 45), 17 : ("f2", 53), } """ # 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. def newNote(time, duration, pitch): track = 0 MyMIDI.addTrackName(track, time, "Sample Track") MyMIDI.addTempo(track, time, 120) channel = 0 volume = 100 MyMIDI.addNote(track, channel, pitch, time, duration, volume) newNote(0, 1, 60) #do newNote(1, 1, 60) #do
# -*- coding: utf-8 -*- import cv2 import copy import numpy as np import dip_lib as dip import sys #importar libreria MIDI, cambiar directorio si es necesario sys.path.append( 'D:/Documentos/Ces/upc/ciclo 6/Procesamiento de Imagenes/Trabajo Final/Trabajo/MIDIUtil-0.89/src/midiutil' ) from MidiFile3 import MIDIFile MyMIDI = MIDIFile(1) # carga imagen de partitura img = dip.load("resource/sheet's/maria.jpg") img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, gray = cv2.threshold(~img_gray, 100, 255, cv2.THRESH_BINARY) # carga de plantillas b1 = cv2.imread("resource/template's/b1.png", 0) b2 = cv2.imread("resource/template's/b3.png", 0) w1 = cv2.imread("resource/template's/w1.png", 0) w2 = cv2.imread("resource/template's/w2.png", 0) r1 = cv2.imread("resource/template's/r1.png", 0) r2 = cv2.imread("resource/template's/r2.png", 0) sol = cv2.imread("resource/template's/sol.png", 0) fa = cv2.imread("resource/template's/fa.png", 0) # se hace uso de cv2.matchTemplate para detectar las posiciones (x,y) de las notas deacuerdo a las plantillas
''' Created on Jul 30, 2013 modified from the single-note-example form midiutil @author: bailey ''' ############################################################################ # A sample program to create a multi-track MIDI file, add notes, # and write to disk. ############################################################################ #Import the library from MidiFile3 import MIDIFile # Create the MIDIFile Object MyMIDI = MIDIFile(2) ### the integer = the number of parallel tracks available # Add track names and tempo. The first argument to addTrackName and # addTempo is the time to write the event. This initialises the tracks. tracks = (0, 1) start_time = 0 MyMIDI.addTrackName(tracks[0], start_time, "Piano") MyMIDI.addTempo(tracks[0], start_time, 120) #MyMIDI.addTrackName(tracks[1],start_time,"Cello") #MyMIDI.addTempo(tracks[1],start_time, 120) # Each track can hold multiple channels, we'll use two for now channels = (0, 1) # Add a note. addNote expects the following information: #channel = some integer >= 0
def main(): root = Tk() root.geometry("750x400+350+300") app = Window(root) root.mainloop() if __name__ == '__main__': main() '''gui stuff: length of piece, tempo, instrument, volume, keys, name''' # Create the MIDIFile Object MyMIDI = MIDIFile(2) ### the integer = the number of parallel tracks available # Add track names and tempo. The first argument to addTrackName and # addTempo is the time to write the event. This initialises the tracks. tracks = (0, 1) start_time = 0 MyMIDI.addTrackName(tracks[0],start_time,"Melody") MyMIDI.addTempo(tracks[0],start_time, properties_list[0]) #MyMIDI.addTrackName(tracks[1],start_time,"Cello") #MyMIDI.addTempo(tracks[1],start_time, 120) # Each track can hold multiple channels, we'll use two for now channels = (0,1,2,3)
''' Created on Jul 30, 2013 @author: bailey ''' ############################################################################ # A sample program to create a multi-track, multi-channel MIDI file, # add notes, and write to disk. ############################################################################ #Import the library from MidiFile3 import MIDIFile # Create the MIDIFile Object MyMIDI = MIDIFile(2) ### the integer = the number of parallel tracks available # Add track names and tempo. The first argument to addTrackName and # addTempo is the time to write the event. This initialises the tracks. tracks = (0, 1) start_time = 0 MyMIDI.addTrackName(tracks[0], start_time, "Piano") MyMIDI.addTempo(tracks[0], start_time, 120) #MyMIDI.addTrackName(tracks[1],start_time,"Cello") #MyMIDI.addTempo(tracks[1],start_time, 120) # Each track can hold multiple channels, we'll use two for now channels = (0, 1) # Add a class_note. addNote expects the following information: #channel = some integer >= 0
DFA = Chord(D, F, A, "minor") CMajorChords.append(DFA) EGB = Chord(E, G, B, "minor") CMajorChords.append(EGB) FAC = Chord(F, A, C, "major") CMajorChords.append(FAC) GBD = Chord(G, B, D, "major") CMajorChords.append(GBD) ACE = Chord(A, C, E, "minor") CMajorChords.append(ACE) BDF = Chord(B, D, F, "diminished") CMajorChords.append(BDF) # Create the MIDIFile Object MyMIDI = MIDIFile(2) # ## the integer = the number of parallel tracks available # Add track names and tempo. The first argument to addTrackName and # addTempo is the time to write the event. This initializes the tracks. tracks = (0, 1) start_time = 0 # I am naming the four parts Soprano, Alto, Tenor Bass, as in choral music MyMIDI.addTrackName(tracks[0], start_time, "Soprano") MyMIDI.addTempo(tracks[0], start_time, 120) MyMIDI.addTrackName(tracks[0], start_time, "Alto") MyMIDI.addTempo(tracks[0], start_time, 120) MyMIDI.addTrackName(tracks[0], start_time, "Tenor") MyMIDI.addTempo(tracks[0], start_time, 120) MyMIDI.addTrackName(tracks[0], start_time, "Bass") MyMIDI.addTempo(tracks[0], start_time, 120)
class Song: def __init__(self, tempo, key, num_measures, instruments, singers, num_tracks): self.num_tracks = num_tracks self.num_measures = num_measures self.MyMIDI = MIDIFile(self.num_tracks + 1) self.instruments = instruments self.singers = singers self.key = key self.time = 0 self.sections = [] # stores the order of song sections. E.g. Chorus, Verse, Bridge self.MyMIDI.addTempo(track=0, tempo=tempo, time=0) self.triads = self.create_triad_sequence(num_measures, key) self.notes_for_track = [[]] # creates the list of notes for each track # sets the unique track and channel number for each singer for x in range(self.num_tracks//3): for singer_index in range(len(self.singers[x])): if self.num_tracks//3*singer_index + x >= 9: # skips over track 10, which is reserved for percussion instruments only self.singers[x][singer_index].track = self.num_tracks//3*singer_index + x + 1 self.singers[x][singer_index].channel = self.num_tracks//3*singer_index + x + 1 else: self.singers[x][singer_index].track = self.num_tracks//3*singer_index + x self.singers[x][singer_index].channel = self.num_tracks//3*singer_index + x # creates the tracks for each singer for singer in [row[0] for row in self.singers]: self.add_track(singer) for singer in [row[1] for row in self.singers]: self.add_track(singer) for singer in [row[2] for row in self.singers]: self.add_track(singer) self.build_song() def add_track(self, singer): self.MyMIDI.addTrackName(singer.track, 0, singer.name + ', Volume:' + str(singer.volume)) self.MyMIDI.addProgramChange(track=singer.track, channel=singer.channel, time=0, program=singer.instrument) self.notes_for_track.append([]) # adds a sublist for the note sequence of the new track def add_single_note(self, singer, pitch, duration): if pitch >= 0: self.MyMIDI.addNote(track=singer.track, channel=singer.track, pitch=pitch, time=self.time, duration=duration, volume=singer.volume) def create_triad_sequence(self, num_triads, key): triads = [] for x in range(num_triads-1): start_note = key.notes_in_key[randint(0,7)] triads.append(triad(key, start_note)) triads.append(triad(key, key.notes_in_key[0])) return triads def return_next_pitch(self, input_singer, input_triad): possible_notes = [] for note in input_triad: note_choices = input_singer.octave_notes_in_range(note) # returns all the octaves of the input_not within the given singer's vocal range for note in note_choices: possible_notes.append(note) # adds notes in the vocal range to the possible_notes list if len(self.notes_for_track[input_singer.track]) > 0: # if it's not the singer's first note previous = self.notes_for_track[input_singer.track][len(self.notes_for_track[input_singer.track])-1] # gets the last note the singer sang jumps = [] steps = [] for note in possible_notes: difference = abs(note-previous) if difference < 5: # if the new note isn't too far from the previous, add to steps list steps.append(note) elif difference <= 12: # if the new note is very far, add it to jumps list jumps.append(note) jump_or_step = randint(0,9) if len(jumps) == 0: # if the jumps list is empty, pick a random step pick_step = randint(0,len(steps)-1) return steps[pick_step] if len(steps) == 0: # if the steps list is empty, pick a random jump pick_jump = randint(0,len(jumps)-1) return jumps[pick_jump] if jump_or_step <= 1: # 1/5 notes will be a jump pick_jump = randint(0,len(jumps)-1) return jumps[pick_jump] else: # 4/5 notes will be steps pick_step = randint(0,len(steps)-1) return steps[pick_step] else: # pick a random note from the possible_notes if it's the singer's first note pick_any = randint(0,len(possible_notes)-1) return possible_notes[pick_any] def build_song(self): section_length = 8 # constant that determines the number of measure in each song section # chorus:0,verse:1,bridge:2 self.build_verse(section_length) # always starts the song with a verse self.sections.append(1) # adds a 1 to self.sections to state that a verse was just played for x in range(self.num_measures//section_length-2): if x != self.num_measures//section_length-2: # if it's not the second to last section choices = [0,1,2] # set possible options to Verse, Chorus, and Bridge choices.pop(self.sections[len(self.sections)-1]) # remove whatever the last section was from the possible options to avoid repetition section_type = choices[randint(0,1)] # pick from the remaining option self.sections.append(section_type) # add the corresponding section number to the list of sections else: # ensures that the second to last measure isn't a chorus choices = [0,1,2] if self.sections[len(self.sections)-1] != 0: # if the last sections wasn't a chorus, remove it as an option as well choices.pop(self.sections[len(self.sections)-1]) choices.pop(0) # removes chorus as an option section_type = choices[0] #selection the only remaining option if section_type == 0: self.build_chorus(section_length) elif section_type == 1: self.build_verse(section_length) elif section_type == 2: self.build_bridge(section_length) self.build_chorus(self.num_measures-(self.time//4)-1) # creates a chorus for the rest of the measure for singer in [row[0] for row in self.singers]: self.build_measure(singer, triad(self.key, self.key.notes_in_key[0]), self.time, [[4],[4],[4],[4]]) # makes a whole note for each singer in the last measure def build_chorus(self, length): # duration_options format [Bass Note lengths:[...], Tenor:[...], Alto:[...], Soprano:[....]] duration_options = [[1,2],[1],[.5,1],[.25,.5]] for x in range(length-1): for singer in [row[0] for row in self.singers]: # for each singer in the chorus section self.build_measure(singer, self.triads[0], self.time, duration_options) self.triads.pop(0) # remove the used triad from the beginning of the sequence self.time += 4 # move the song time to the next measure for singer in [row[0] for row in self.singers]: self.build_measure(singer, triad(self.key, self.key.notes_in_key[0]), self.time, duration_options) # end the section on the I chord self.triads.pop(0) self.time+=4 def build_verse(self, length): duration_options = [[1,2,4],[1,2],[.5,1],[.25,.5,1]] for x in range(length-1): for singer in [row[1] for row in self.singers]: self.build_measure(singer, self.triads[0], self.time, duration_options) self.triads.pop(0) self.time += 4 for singer in [row[1] for row in self.singers]: self.build_measure(singer, triad(self.key, self.key.notes_in_key[0]), self.time, duration_options) self.triads.pop(0) self.time+=4 def build_bridge(self, length): duration_options = [[2],[1],[.25,.5,1],[.25,.5,1]] for x in range(length-1): for singer in [row[2] for row in self.singers]: self.build_measure(singer, self.triads[0], self.time, duration_options) self.triads.pop(0) self.time += 4 for singer in [row[2] for row in self.singers]: self.build_measure(singer, triad(self.key, self.key.notes_in_key[0]), self.time, duration_options) self.triads.pop(0) self.time+=4 def build_measure(self, singer, input_triad, time, note_options): orig_time = deepcopy(time) # ensures the original input isn't edited, only a copy if singer.name == 'Bass': duration_options = note_options[0] elif singer.name == 'Tenor': duration_options = note_options[1] elif singer.name == 'Alto': duration_options = note_options[2] elif singer.name == 'Soprano': duration_options = note_options[3] while time < orig_time + 4: if time > orig_time + 3: # if there is less than one beat left in the measure temp_options = [duration for duration in duration_options if time+duration <= (orig_time+4) and duration!=.25] # only add a note that will fit in the measure but also don't add a 1/16 note because they come in sets of 4 else: temp_options = [duration for duration in duration_options if time+duration <= (orig_time+4)] # only add a note that will fit in the measure duration = temp_options[randint(0,len(temp_options)-1)] # pick a random duration if duration == .25: for x in range(4): # if a 1/16 notes, add 4 of them self.build_beat(input_triad, time, singer, duration) time += .25 else: # otherwise just build a new note self.build_beat(input_triad, time, singer, duration) time += duration def build_beat(self, input_triad, time, singer, duration=1): pitch = self.return_next_pitch(singer, input_triad) self.notes_for_track[singer.track].append(pitch) self.MyMIDI.addNote(singer.track, singer.track, pitch, time, duration, singer.volume) def write_to_disk(self, output_name): binfile = open(r'Songs/{}.mid'.format(output_name), 'wb') self.MyMIDI.writeFile(binfile) binfile.close() print("Written to file with name: '{}'!".format(output_name + '.mid'))
''' Created on Jul 30, 2013 @author: bailey ''' ############################################################################ # A sample program to create a multi-track, multi-channel MIDI file, # add notes, and write to disk. ############################################################################ #Import the library from MidiFile3 import MIDIFile # Create the MIDIFile Object MyMIDI = MIDIFile(2) ### the integer = the number of parallel tracks available # Add track names and tempo. The first argument to addTrackName and # addTempo is the time to write the event. This initialises the tracks. tracks = (0, 1) start_time = 0 MyMIDI.addTrackName(tracks[0],start_time,"Piano") MyMIDI.addTempo(tracks[0],start_time, 120) #MyMIDI.addTrackName(tracks[1],start_time,"Cello") #MyMIDI.addTempo(tracks[1],start_time, 120) # Each track can hold multiple channels, we'll use two for now channels = (0,1) # Add a class_note. addNote expects the following information: #channel = some integer >= 0
def Scale2MIDI(self): # method to produce a scale MyMIDI = MIDIFile(1) # create a midifile self.tracks = (0, 1) start_time = 0 # starting time is initialized to be 0 MyMIDI.addTrackName(self.tracks[0], start_time, "Scale") MyMIDI.addTempo(self.tracks[0], start_time, 80) self.channels = (0, 1) volume_On = 95 # on-beats are accentuated volume_Off = 80 # off-beats are attenuated if self.flavor == "Major": music = class_Keys.Majors(self.Key) elif self.flavor == "Minor": music = class_Keys.Minors(self.Key) # write the music on the key that the user has specified i = 0 while i < len(music.output): # remember music.output is a big list of ''lists of pitch numbers'' j = 0 while j < len(music.output[i]): if j == 0: # accentuate the on the beats MyMIDI.addNote(self.tracks[0], self.channels[0], music.output[i][j], start_time, 1 / 3, volume_On) start_time += 1 / 3 j += 1 else: # off-beats attenuation MyMIDI.addNote(self.tracks[0], self.channels[0], music.output[i][j], start_time, 1 / 3, volume_Off) start_time += 1 / 3 j += 1 i += 1 binfile = open("Scale.mid", 'wb') # write the scale to a file named "Scale.mid" MyMIDI.writeFile(binfile) binfile.close() print('A file named Scale.mid has been generated for you. This file contains the entire scales of the key chosen.')
class Composition: def __init__(self): # these values are all entered by the user via the GUI self.TimeSig = None # get the time signature self.Key = None # on which key should the music be written? gathered from user self.Form = None # for later use if we try to write certain forms of music (Sonata, Concerto, Ritornello, etc.) self.Genre = None # for later use if we try to include playing techniques related to certain genre (add syncopations for Jazz, etc) self.flavor = None self.instrs = dict([('piano', 0), ('harpsichord', 6), ('glock', 9), ('vibes', 11), ('marimba', 12), ('organ', 19), ('guitar', 24), ('bass', 32), ('violin', 40), ('viola', 41), ('cello', 42), ('contrabass', 43), ('harp', 46), ('timps', 47), ('voice', 54), ('trumpet', 56), ('tuba', 58), ('horn', 60), ('alto sax', 65), ('oboe', 68), ('bassoon', 70), ('clarinet', 71), ('flute', 73), ('recorder', 74), ('bottle', 75), ('whistle', 78), ('fifths', 96), ('halo', 94), ('goblins', 101), ('koto', 107), ('bagpipe', 109), ('taiko', 116), ('toms', 117), ('breath', 121), ('seashore', 122), ('bird', 123), ('phone', 124), ('applause', 126)]) # dictionary of possible instruments, linking the string name of the instrument to its number so that it can be accessed in the Midi file self.MyMIDI = MIDIFile(1) self.tracks = (0, 1) self.channels = (0, 1, 2, 3) # four channels, (one for Soprano, Alto, Tenor, Bass) self.length = 20 # 20 as the default number of measures def getLength(self, number): # 10, 20, and 30 are the possible number of measures for a piece (chosen by the user in the GUI) if number == "10": self.length = 10 if number == "20": self.length = 20 if number == "30": self.length = 30 def getTimeSig(self, number): loop = True # print('--------------------------------------------') # print('There are 2 types of time signature can be chosen. Enter 3 for 3/4, or 4 for 4/4 ...') while loop: try: # trying to handle errors with exceptions # num = input() # if int(num) != 3 and int(num) != 4: if number != 3 and number != 4: raise errors.nonPositive(number) # 3/4 and 4/4 are the only possible time signatures--raise an error if a different value is inputted. else: loop = False except errors.nonPositive: # if the error is raised print a useful message to the screen print('The time signature can only be 3 or 4!') print('Enter the number of measures you would like to have in the composition...') loop = True except ValueError: print('Oops, something is not right! Gotta tidy up!') print('Enter the number of measures you would like to have in the composition...') loop = True self.TimeSig = number def getMeasureNum(self): # we are not currently using this method, but it was written earlier when our code was using input at the keyboard rather than a GUI loop = True print('--------------------------------------------') print('Enter the number of measures you would like to have in the composition...') while loop: try: # trying to handle errors with exceptions num = input() if int(num) <= 0: raise errors.nonPositive(int(num)) # again, raise an error in the event the input isn't a positive integer. else: loop = False except errors.nonPositive: print('The measure number should be a positive integer!') print('Enter the number of measures you would like to have in the composition...') loop = True except ValueError: print('Oops, something is not right! Gotta tidy up!') print('Enter the number of measures you would like to have in the composition...') loop = True self.MeasureNum = num # simple methods to get the Key, flavor, and to change the instrument def getKey(self, number): self.Key = number def getFlavor(self, flavor): self.flavor = flavor def changeInstr(self, channel, time, instr): self.MyMIDI.addProgramChange(self.tracks[0], channel, time, instr) def Scale2MIDI(self): # method to produce a scale MyMIDI = MIDIFile(1) # create a midifile self.tracks = (0, 1) start_time = 0 # starting time is initialized to be 0 MyMIDI.addTrackName(self.tracks[0], start_time, "Scale") MyMIDI.addTempo(self.tracks[0], start_time, 80) self.channels = (0, 1) volume_On = 95 # on-beats are accentuated volume_Off = 80 # off-beats are attenuated if self.flavor == "Major": music = class_Keys.Majors(self.Key) elif self.flavor == "Minor": music = class_Keys.Minors(self.Key) # write the music on the key that the user has specified i = 0 while i < len(music.output): # remember music.output is a big list of ''lists of pitch numbers'' j = 0 while j < len(music.output[i]): if j == 0: # accentuate the on the beats MyMIDI.addNote(self.tracks[0], self.channels[0], music.output[i][j], start_time, 1 / 3, volume_On) start_time += 1 / 3 j += 1 else: # off-beats attenuation MyMIDI.addNote(self.tracks[0], self.channels[0], music.output[i][j], start_time, 1 / 3, volume_Off) start_time += 1 / 3 j += 1 i += 1 binfile = open("Scale.mid", 'wb') # write the scale to a file named "Scale.mid" MyMIDI.writeFile(binfile) binfile.close() print('A file named Scale.mid has been generated for you. This file contains the entire scales of the key chosen.') def Measure_rythm(self, time): # list of lists of potential rythms that can be chosen from. Each is a full measure long. Rythms4 = [[1, 1 / 2, 1 / 2, 1, 1], [1 / 3, 1 / 3, 1 / 3, 1, 1, 1 / 2, 1 / 2], [1 / 2, 1 / 2, 1 / 2, 1 / 4, 1 / 4, 1 / 4, 1 / 4, 1 / 2, 1], [1 / 2, 1 / 2, 1, 1 / 2, 1 / 2, 1], [1, 1, 1, 1]] Rythms3 = [[1, 1, 1], [1 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 3], [1 / 2, 1 / 2, 1, 1], [1 / 4, 1 / 4, 1 / 4, 1 / 4, 1 / 2, 1 / 2, 1 / 2, 1 / 2], [1, 1 / 4, 1 / 4, 1 / 4, 1 / 4, 1 / 2, 1 / 2]] if time == 4: # for each time signature, choose from the proper list of rhythms. rythm = random.choice(Rythms4) if time == 3: rythm = random.choice(Rythms3) return rythm # return the randomly chosen rhythm def Compose(self): start_time = 0 # starting time is initialized to be 0 start_time_1 = 0 self.MyMIDI.addTrackName(self.tracks[0], start_time, "Melody") self.MyMIDI.addTempo(self.tracks[0], start_time, 90) self.channels = (0, 1, 2, 3) volume_On = 110 # on-beats are accentuated volume_Second_On = 90 # for beats at the front of a triplet but not on the beats volume_Off = 50 # off-beats are attenuated if self.flavor == "Minor": music = class_Keys.Minors(self.Key) # write the music on the key that the user has specified elif self.flavor == "Major": music = class_Keys.Majors(self.Key) temp = [0, 0, 0] # variable to store the triads, each time stores a new triad hasn't stored before j = 0 while j < self.length: # j is the number of measure triad_1 = random.choice([ x for x in music.listOfTriads if x != temp]) rythm = self.Measure_rythm(int(self.TimeSig)) # begin to generate a whole measure for the soprano for k in rythm: # grab notes for each time slots self.MyMIDI.addNote(self.tracks[0], self.channels[0], random.choice(triad_1.friend.notes) + 12, start_time, k, volume_Second_On) # soprano up an octave, (generate range) start_time += k # k=0 # while k < int(len(rythm)): # grab notes for each time slots # self.MyMIDI.addNote(self.tracks[0], self.channels[0], random.choice(triad_1.friend.notes) + 12, start_time, rythm[k], volume_Second_On) # start_time += rythm[k] # k += 1 # here we start to generate the notes for other 3 parts: i = 0 while i < int(self.TimeSig): # i keeps track of the beats in a full measure choice_1 = random.choice(triad_1.friend.notes) # "choices" generate notes for a harmonizing triad choice_2 = random.choice([x for x in triad_1.friend.notes if x != choice_1]) choice_3 = random.choice([x for x in triad_1.friend.notes if x != choice_1 and x != choice_2]) if i == 0: # add a chord in the alto, tenor, and bass to correspond with the first on beat self.MyMIDI.addNote(self.tracks[0], self.channels[1], choice_1, start_time_1, 2, volume_Off) # establish range--alto stays where it is, tenor down an octave, bass down two octaves self.MyMIDI.addNote(self.tracks[0], self.channels[2], choice_2 - 12, start_time_1, 2, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], choice_3 - 24, start_time_1, 2, volume_Off) start_time_1 += 2 i += 2 if i == 2: # add a chord in the alto, tenor and bass to correspond with the second on beat choice_1 = random.choice(triad_1.friend.notes) choice_2 = random.choice([x for x in triad_1.friend.notes if x != choice_1]) choice_3 = random.choice([x for x in triad_1.friend.notes if x != choice_1 and x != choice_2]) if self.TimeSig == 3: # separate code for 3/4 and 4/4 music self.MyMIDI.addNote(self.tracks[0], self.channels[1], choice_1, start_time_1, 1, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], choice_2 - 12, start_time_1, 1, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], choice_3 - 24, start_time_1, 1, volume_Off) start_time_1 += 1 i += 1 else: # if self.TimeSig == 4: self.MyMIDI.addNote(self.tracks[0], self.channels[1], choice_1, start_time_1, 2, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], choice_2 - 12, start_time_1, 2, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], choice_3 - 24, start_time_1, 2, volume_Off) start_time_1 += 2 i += 2 j += 1 # increment j to keep composing temp = triad_1 # update temp # add a coda after the while j loop--different code for each possible combination of flavor and time signature (4 possibilities) if self.flavor == "Major" and int(self.TimeSig) == 3: self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 16, start_time, 1, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 11, start_time_1, 3, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 5, start_time_1, 3, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root + 2, start_time_1, 3, volume_Off) start_time += 1 # increment the start time start_time_1 += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 14, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 11, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 12, start_time, 3, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 7, start_time_1, 3, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 4, start_time_1, 3, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root, start_time_1, 3, volume_Off) elif self.flavor == "Major" and int(self.TimeSig) == 4: self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 4, start_time, 1, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 11, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 5, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root + 2, start_time_1, 4, volume_Off) start_time += 1 start_time_1 += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 16, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 14, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 11, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 12, start_time, 4, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 7, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 4, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root, start_time_1, 4, volume_Off) elif self.flavor == "Minor" and int(self.TimeSig) == 3: self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 15, start_time, 1, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 11, start_time_1, 3, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 5, start_time_1, 3, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root + 2, start_time_1, 3, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 14, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 11, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 12, start_time, 3, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 7, start_time_1, 3, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 3, start_time_1, 3, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root, start_time_1, 3, volume_Off) elif self.flavor == "Minor" and int(self.TimeSig) == 4: self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 3, start_time, 1, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 11, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 5, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root + 2, start_time_1, 4, volume_Off) start_time += 1 start_time_1 += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 15, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 14, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 11, start_time, 1, volume_Second_On) start_time += 1 self.MyMIDI.addNote(self.tracks[0], self.channels[0], music.root + 12, start_time, 4, volume_Second_On) self.MyMIDI.addNote(self.tracks[0], self.channels[1], music.root + 7, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[2], music.root + 3, start_time_1, 4, volume_Off) self.MyMIDI.addNote(self.tracks[0], self.channels[3], music.root, start_time_1, 4, volume_Off) binfile = open("output.mid", 'wb') # write the music to a file! self.MyMIDI.writeFile(binfile) binfile.close()
############################################################################ # A sample program to create a single-track MIDI file, add a class_note, # and write to disk. ############################################################################ #Import the library from MidiFile3 import MIDIFile # 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 class_note. addNote expects the following information: channel = 0 pitch = 60 duration = 1 volume = 100 # Now add the class_note. MyMIDI.addNote(track,channel,pitch,time,duration,volume) # And write it to disk. binfile = open("SingleNote.mid", 'wb') MyMIDI.writeFile(binfile) binfile.close()