예제 #1
0
파일: SongBuilder.py 프로젝트: brodyzt/HW-5
    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()
예제 #2
0
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()
예제 #3
0
 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
예제 #4
0
'''
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
예제 #5
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
예제 #7
0
'''
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
예제 #8
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)
예제 #9
0
'''
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
예제 #10
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)
예제 #11
0
파일: SongBuilder.py 프로젝트: brodyzt/HW-5
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'))
예제 #12
0
'''
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
예제 #13
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.')
예제 #14
0
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()
예제 #15
0
############################################################################
# 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()