Пример #1
4
    def generate(self, length, bars, octave, scale=["C", "D", "E", "G", "A"], instrument=1, rand_length=False,
                 time_signature=(4, 4), velocity=[64, 64], channel=1, rests=True, rule_number=30):
        # create the instrument for the main track
        instr = MidiInstrument()
        instr.instrument_nr = instrument  # MIDI instrument number: http://www.midi.org/techspecs/gm1sound.php
        track = containers.Track(instr)
        self.set_instrument(instrument)
        if not self.initial:
            self.initial = [False] * 9
            print "Error: initial set empty. Defaulting..."

        if rand_length:  # start with quarter note as base
            length = 4

        automata = Engine(rule_number, init_row=self.initial, edge_type=EdgeType.LOOP)

        # Index counting for diagnostics
        self.counts = dict((n, 0) for n in range(0, len(scale) * 2))
        index = 5  # starting value
        for b in range(0, (length * bars) / 4):
            bar = Bar("C", time_signature)
            while bar.space_left() != 0:  # runs until we're out of space for notes (e.g. complete bar)
                automata.step()  # take a step
                index = self.get_chosen_note(index, automata.rows[-1])
                if rand_length:  # if we're randomly generating lengths of notes
                    length = int(math.pow(2, random.randint(1, 4)))
                    left = bar.space_left()
                    space = (
                        (left - (left % 0.25)) * 16) if left > 0.25 else left * 16  # checks if we have enough space
                    if space < 16 / length:
                        length = int(16.0 / space)
                if rests and random.randint(0, 20) == 1:  # same rest generation
                    bar.place_rest(16)
                    continue  # skip the rest
                name = list(scale)[index if index < 5 else index - 4]  # can be used for diagnostics
                self.counts[index] += 1  # add to count data
                self.notes.append(index)
                n = Note(name,
                         octave=octave if index < 5 else octave + 1)
                n.set_velocity(random.randint(velocity[0], velocity[1]))  # random velocity, can feel more "real"
                n.set_channel(channel)  # if we want > 1 instruments we need > 1 channel
                bar.place_notes(n, length)
                # print self.format_block(automata.rows[-1])
            track.add_bar(bar)  # add bar to track
        self.track = track  # set our track object to the newly generated track
        # for n in self.counts:
        #     print str(n) + ": " + str(self.counts[n])  # diagnostics
        # print "======="
        return self
Пример #2
1
    def load_from_song(self, song):
        ''' Fills a mingus-composition object with the data of a Song object '''

        if 'bar_length' in song.info:
            try:
                self.bar_length = song.info['bar_length']
            except:
                print ("You need to specify length of a Bar first before you can do this")
        for line in song.lines:
            track = Track()
            bar = Bar()
            for segment in line.segments:
                if segment.type == 'pause':
                    int_val = None
                elif segment.type == 'note':
                    int_val = segment.pitch
                n = Note().from_int(int_val + 48)
                note_length = float(self.bar_length) / segment.duration
                if not bar.place_notes(n, note_length):
                    track.add_bar(bar)
                    bar = Bar()
                    bar.place_notes(n, note_length)
            track.add_bar(bar)
            self.composition.add_track(track)
        self.path = song.path
        self.song_name = song.reader.file_name[:-4]
def figGround():
    # Purpose: Do a dictation of one instrument while other instruments are distracting in background.
    numnotes = setDuration()
    loopDictation = True

    while (loopDictation):
        randInstrument(1,
                       set([
                           0, 1, 2, 4, 6, 24, 25, 26, 27, 28, 29, 40, 41, 42,
                           56, 57, 60, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
                           78, 79, 80, 81, 82, 83, 85, 102, 103, 104, 105, 108,
                           109
                       ]))  # Set lead/figure instr
        randInstrument(2,
                       set([
                           44, 45, 48, 49, 50, 51, 52, 53, 54, 55, 61, 62, 63,
                           86, 87, 88, 89, 90, 91, 92, 93
                       ]))  # Set pad/ground instr

        randLeadNotes = []
        for i in range(0, numnotes):
            randPitch = Note(12 * randint(3, 6) + randint(0, 12))
            #            randChord =
            randLeadNotes.append(randPitch)

        randBar = Bar()
        for n in randLeadNotes:
            randBar.place_notes(n, 4)

        playBeforeAnswer(randBar)
        print(randNotes)
        loopDictation = playAfterAnswer(randBar)

    print("\n")
Пример #4
0
 def grid_to_bar(self):
     bar = Bar()
     bar.length = self.size
     for col in xrange(self.size):
         notes = self.column_to_notes(col)
         bar.place_notes(notes, 4)
     return bar
Пример #5
0
def solo_bar(chord_name):
	scale = generate_scale(chord_name)
	# note = random.choice(chords.from_shorthand(chord_name))
	# note_index = scale.index(note)
	note_index = random.randrange(len(scale))
	note = scale[note_index]
	beat = 0
	duration = 1
	bar = Bar()
	while beat < 1:
		if beat % .25 == 0:
			duration = random.choice([4, 8, 16])
		stepwise = random.randrange(5) != 0
		rest = random.randrange(10) < 3
		if rest:
			bar.place_notes(None, duration)
		else:
			if stepwise:
				interval = random.choice([-1, 1])
			else:
				interval = random.randrange(len(scale))
			note_index = ((note_index+interval)+len(scale))%len(scale)
			note = scale[note_index]
			bar.place_notes(note, duration)
			print(note)
		beat = bar.current_beat
	print("---")
	return bar
Пример #6
0
def init_random_track(key, is_subject=True):
    notes = keys.get_notes(key)
    bar = Bar(key=key)
    while bar.current_beat < 1:
        # Randomize pitch and duration of each note.
        duration = 2**random.randint(1, 3)
        pitch = notes[random.randint(0, 6)]

        # If it is intened to be a subject, set the first note to the root.
        if bar.current_beat == 0 and is_subject == True:
            pitch = notes[0]

        # If the randomized duration doesn't fit in the bar, make it fit
        if 1 / duration > 1 - bar.current_beat:
            duration = 1 / (1 - bar.current_beat)

        # Place the new note in the bar
        bar.place_notes(pitch, duration)

    # Create a track to contain the randomized bar
    track = Track()
    track + bar

    # Return the track
    return track
Пример #7
0
    def gen_with_rhythm(self,proggresion,rhythm,diatonic):
        self.get_meter_from_rhythm(rhythm)
        bar = Bar(key = diatonic[0],meter = self.get_meter_from_rhythm(rhythm))

        for i in range(len(proggresion)):
            bar.place_notes(proggresion[i],rhythm[i])

        return bar
Пример #8
0
 def gen_simple(self,diatonic,note_length,proggresion):
     """generation of a simple song ,each note has the same length"""
     
     bar = Bar(diatonic[0],(len(proggresion),note_length))
     
     for i in proggresion:
         bar.place_notes(i,note_length)
     
     return bar 
Пример #9
0
 def set_as_beat_strum(self):
     self.bars = []
     for ch in self.chords:
         b = Bar(key=self.key)
         i = 0
         while i<4:
             b.place_notes(ch, 4)
             i += 1
         self.add_bar(b)
Пример #10
0
 def set_as_beat_strum(self):
     self.bars = []
     for ch in self.chords:
         b = Bar(key=self.key)
         i = 0
         while i < 4:
             b.place_notes(ch, 4)
             i += 1
         self.add_bar(b)
Пример #11
0
def random_bar(chord_name):
	scale = generate_scale(chord_name)
	bar = Bar()
	beat = 0
	while beat < 1:
		duration = random.choice([4, 8, 16])
		note = random.choice(scale)
		bar.place_notes(note, duration)
		beat = bar.current_beat
	return bar
Пример #12
0
 def fill_bars(self, arpeggio, note_duration = 16, bars = 1):
     generator = arpeggio.get_generator()
     while bars > 0:
         b = Bar()
         b.key = 'C'
         while not b.is_full():
             b.place_notes(generator.next(), note_duration)
         self.track.add_bar(b)
         bars -= 1
     return self.track
Пример #13
0
 async def on_start(self):
     self.agent.set("current_bar_no", 0)  # inicializa "current_bar_no" en 0
     # self.agent.set("tempo", 120)
     # self.agent.set("key", "C")
     self.agent.set("melody_track", Track())
     self.agent.set("accompaniment_track", Track())
     self.agent.set("current_melody_bar",
                    Bar(CFG.SONG_KEY_SIGNATURE, CFG.SONG_TIME_SIGNATURE))
     self.agent.set("current_accompaniment_bar",
                    Bar(CFG.SONG_KEY_SIGNATURE, CFG.SONG_TIME_SIGNATURE))
Пример #14
0
def fix_track_bar(bar):
    if type(bar) == list: # i.e. not Bar
        if bar == []:
            return []
        if len(bar[0]) > 1: # len=3 if list [[a, b, NoteContainer]] 
            b = Bar()
            b.place_notes(bar[0][2], bar[0][1])
            bar = b
        else: # if list like [Bar] or [Bar, Bar] (hopefully no [Bar]x3's)
            return bar
    return [bar]      
Пример #15
0
 async def run(self):
     cbn = self.agent.get("current_bar_no")
     if cbn < CFG.SONG_LENGTH:  # falta sacar con modulo, de momento es un acorde por barra
         msg = await self.receive()
         if msg:
             if self.agent.get("chords_template").match(msg):
                 if chords.determine_triad(
                         getattr(chords, CFG.PROGRESSIONS[cbn])(
                             CFG.SONG_KEY_SIGNATURE),
                         True) == chords.determine_triad(
                             msg.body.split(','), True):
                     cab = self.agent.get("current_accompaniment_bar")
                     cab.place_notes(msg.body.split(','),
                                     1)  # de momento es un acorde por barra
                     at = self.agent.get("accompaniment_track")
                     at.add_bar(cab)
                     self.agent.set(
                         "current_accompaniment_bar",
                         Bar(CFG.SONG_KEY_SIGNATURE,
                             CFG.SONG_TIME_SIGNATURE))
                     self.agent.set("accompaniment_track", at)
                     self.set_next_state(S_RECEIVE_NOTE)
                 else:
                     self.set_next_state(
                         S_RECEIVE_CHORD)  # Continúa en el mismo estado
             else:
                 self.set_next_state(
                     S_RECEIVE_CHORD)  # Continúa en el mismo estado
         else:
             self.set_next_state(
                 S_RECEIVE_CHORD)  # Continúa en el mismo estado
     else:
         self.set_next_state(S_PUBLISH_SONG)
Пример #16
0
 def __init__(self, starting_note='C-3'):
     fluidsynth.init(path_to_instrument, audio_driver)
     self.starting_note = Note(starting_note)
     self.relative_major_scale = np.array([0, 2, 4, 5, 7, 9, 11])
     self.scale = self.relative_major_scale + int(self.starting_note)
     self.note = Note(self.starting_note)
     self.bar = Bar()
     fluidsynth.play_Note(self.note)
Пример #17
0
Файл: song.py Проект: tewe/canta
    def load_from_song(self, song):
        ''' Fills a mingus-composition object with the data of a Song object '''

        if 'bar_length' in song.info:
            try:
                self.bar_length = song.info['bar_length']
            except:
                print "You need to specify length of a Bar first before you can do this"
        for line in song.lines:
            track = Track()
            bar = Bar()
            for segment in line.segments:
                if segment.type == 'pause':
                    int_val = None
                elif segment.type == 'note':
                    int_val = segment.pitch
                n = Note().from_int(int_val + 48)
                note_length = float(self.bar_length) / segment.duration
                if not bar.place_notes(n, note_length):
                    track.add_bar(bar)
                    bar = Bar()
                    bar.place_notes(n, note_length)
            track.add_bar(bar)
            self.composition.add_track(track)
        self.path = song.path
        self.song_name = song.reader.file_name[:-4]
Пример #18
0
def Bars_from_list(listb=[[0.0, 8.0, None],[0.125, 8.0, ['C-5']]]):
    '''
    Helps TinyDB de-serialisation (load)
    Input list of (representations of) bars of the form [[position,duration,[note(s)]] , ...]
    Places these note events into Bar objects and returns as a list of Bars
    '''
    #listb = [notev[0] if len(notev) == 1 else notev for notev in listb] # commented out as was repeating whole bars (notev = [whole bar note container nc])
    listb = [nc if type(notev[0])!=float else notev for notev in listb for nc in notev]
    b = Bar() # we're instantiating Bars so I'm not sure why the outputs are sometimes type [list]..., cf fix_track_bar()
    bars = [b]
    for notev in listb:
        if notev != []:
            if bars[-1].place_notes(notev[2], notev[1]):
                pass
            else:
                bars.append(Bar())
                bars[-1].place_notes(notev[2], notev[1])
    return bars
Пример #19
0
def notes_durations_to_track(_notes, durations=None):
    '''
    params:
    - _notes: list of list of Notes [['G','B','D','F'], ['C','E','G','B']]
    - durations: Durations should be a list of integers e.g. [2,2,1] will give | chord 1 chord 2 | chord 3 |

    TO-DO: 
        - mingus durations are limited to =< 1 bar; we want to be able to parse a duration of '0.5' (because in mingus '4'=crotchet i.e. num subdivs) to refer to 2 bars (just use 1/d)
    
    '''
    if durations is None:
        durations = [1] * len(_notes)

    t = Track()
    for i, _note in enumerate(_notes):
        b = Bar()
        b.place_notes(_note, durations[i])
        t.add_bar(b)
    return t
Пример #20
0
def sheets_from_peaks(peaks):
    """Generate and open the sheet music pdf that represents the notes contained in peaks."""

    bass_range = Instrument()
    bass_range.set_range(['A-0', 'C-4'])
    bass_track = Track(bass_range)

    treble_range = Instrument()
    treble_range.set_range(['C-4', 'C-8'])
    treble_track = Track(treble_range)

    treble_track.add_bar(Bar())
    bass_track.add_bar(Bar())

    for time_slice in peaks:
        bass_chord, treble_chord = [], []
        for note_index, note_value in enumerate(time_slice):
            if note_value:
                # add 9 to note_index to start at A-0
                note = Note().from_int(note_index + 9)
                if bass_range.note_in_range(note):
                    bass_chord.append(note)
                elif treble_range.note_in_range(note):
                    treble_chord.append(note)
        if bass_chord == treble_chord == []:
            continue
        for chord, track in ((bass_chord, bass_track), (treble_chord,
                                                        treble_track)):
            if track.bars[-1].is_full():
                track.add_bar(Bar())
            if chord:
                print chord
                track.bars[-1] + chord
                print track
            else:
                track.bars[-1].place_rest(4)

    print bass_track
    print treble_track
    merge_rests(treble_track, bass_track)
    save_and_print(treble_track, bass_track)
Пример #21
0
    def play(self, melody, chords, bpm, scores, bars, key, mode, modeToPass,
             tra, file, out_dir):
        t2 = Track()
        sh = progressions.to_chords(chords, key)
        for i in range(0, len(sh)):
            b = Bar(None, (4, 4))
            if len(chords[i][0]) > 5:
                b.place_notes(None, 1)
            else:
                b.place_notes(NoteContainer(sh[i]), 1)
            t2 + b
        fluidsynth.pan(1, 25)
        fluidsynth.pan(2, 120)
        fluidsynth.main_volume(2, 50)
        fluidsynth.play_Tracks([melody, t2], [1, 2], bpm)

        # sleep(500000)

        button = Button(text='Clique para rearmonizar!',
                        command=lambda: self.checkReharmonize(
                            chords, scores, bars, key, mode, modeToPass, tra,
                            bpm, file, out_dir),
                        bg='brown',
                        fg='white',
                        font=('helvetica', 9, 'bold'))
        self.canvas1.create_window(200, 250, window=button)
Пример #22
0
def NewTrack(beats, count, withChromatics, with16):
    """
    NewTrack(liczba_uderzeń_w_takcie, liczba_taktów, czy_z_chromatyką, czy_z_16)
    zwraca krotkę z trackiem i liczbą nut
    """
    track = Track(Instrument())
    rhythms = []
    noOfNotes = 0
    melodyCount = 0

    for ii in range(count):
        rhythms.append(newBarRhythm(beats, with16))
        noOfNotes += len(rhythms[ii])

    if withChromatics:
        melody = newMelody(noOfNotes)
    else:
        melody = newMelodyWithoutChromatics(noOfNotes)

    for rhythm in rhythms:
        b = Bar("C", (beats, 4))
        for note in rhythm:
            k = random.random()
            if k > pOfRests:
                b.place_notes(melody[melodyCount], 4 / note)
            else:
                b.place_notes(None, 4 / note)
            melodyCount += 1
        track + b
    return (track, melodyCount)
Пример #23
0
def easy_bar(notes, durations=None):
    _default_note_duration = 4
    if not durations and notes is not None:
        durations = [_default_note_duration] * len(notes)

    # setup Bar object
    bar = Bar()
    if (isinstance(notes, NoteContainer) or isinstance(notes, Note)
            or notes is None):
        bar.place_notes(notes, _default_note_duration)
    elif notes is None:
        bar.place_notes(notes, _default_note_duration)
    else:
        for x, d in zip(notes, durations):
            bar.place_notes(x, d)
    return bar
Пример #24
0
def get_bar_from_chord(chord):
	chord = make_ascending(chord)
	# print chord

	b = Bar(meter=(len(chord) + 1, 4))
	for n in chord:
		b.place_notes(n, 4)  ## add quarter note
	b.place_notes(chord, 4)
	return b
def melDict():
    # TO DO: Be able to set options here (how long is dictation, range, etc.)
    #    setPitchSet()
    numnotes = setDuration()
    loopDictation = True

    while (loopDictation):
        randInstrument(1)

        randNotes = []
        randBar = Bar()
        for i in range(0, numnotes):
            randPitch = Note(12 * randint(3, 6) + randint(0, 12))
            randNotes.append(randPitch)
            randBar.place_notes(randPitch, 4)

        #for n in randNotes:
    #     randBar.place_notes(n, 4)

        playBeforeAnswer(randBar)
        print(randNotes)
        loopDictation = playAfterAnswer(randBar)

    print("\n")
Пример #26
0
def get_bar_from_triad(triad):
    assert len(triad) == 3
    triad = make_ascending(triad)
    # print triad

    b = Bar()
    for n in triad:
        b.place_notes(n, 4)  ## add quarter note
    b.place_notes(triad, 4)
    return b
Пример #27
0
def get_bar_from_interval(interval):
    assert len(interval) == 2
    interval = make_ascending(interval)
    # print interval

    b = Bar()
    for n in interval:
        b.place_notes(n, 4)
    b.place_notes(interval, 2)
    return b
Пример #28
0
 def fill_bars(self, arpeggio, note_duration=16, bars=1):
     generator = arpeggio.get_generator()
     while bars > 0:
         b = Bar()
         b.key = 'C'
         while not b.is_full():
             b.place_notes(generator.next(), note_duration)
         self.track.add_bar(b)
         bars -= 1
     return self.track
Пример #29
0
 def write_mingus(self, outfile):
     notes = list(self.timeseries['Notes'])
     t = Track()
     for n in range(len(notes)):
         if n % 4 == 0:
             b = Bar(self.key, (4, 4))
         if notes[n] != 'Z':
             b + notes[n]
         else:
             b + None
         if (n + 1) % 4 == 0:
             t + b
     self.composition + t
     self.track = t
     lily_composition = LilyPond.from_Composition(self.composition)
     print lily_composition
     LilyPond.to_pdf(lily_composition, outfile)
def createMingusComposition(intermed, timesig, bIsTreble, bSharps):
    comp = Composition()
    comp.set_title('Trilled Results')
    comp.set_author('Author')
    if bIsTreble: ins = TrebleInstrument('')
    else: ins = BassInstrument('')

    track = Track(ins)
    track.name = 'Part 1'
    comp.add_track(track)

    assert len(timesig) == 2 and isinstance(timesig[0], int) and isinstance(
        timesig[1], int)
    firstbar = Bar(meter=timesig)
    track.add_bar(firstbar)

    mapDurs = {
        int(intermed.baseDivisions * 4): 1.0,  #whole note,
        int(intermed.baseDivisions * 2): 2.0,  #half note
        int(intermed.baseDivisions * 1): 4.0,  #qtr note, and so on
        int(intermed.baseDivisions * 0.5): 8.0,
        int(intermed.baseDivisions * 0.25): 16.0,
        int(intermed.baseDivisions * 0.125): 32.0,
        int(intermed.baseDivisions * 0.0625): 64.0,
    }

    for note in intermed.noteList:
        if note.pitch == 0 or note.pitch == (0, ):  # a rest
            thepitches = tuple()
        else:  # a note
            thepitches = []
            for pitch in note.pitch:
                pname, poctave = music_util.noteToName(pitch, bSharps)
                thepitches.append(pname + '-' + str(poctave))

        dur = note.end - note.start
        if dur not in mapDurs:
            raise NotesinterpretException('Unknown duration:' + str(dur))
        notecontainer = NoteContainer(thepitches)
        notecontainer.tied = note.isTied
        bFit = track.add_notes(notecontainer, mapDurs[dur])
        assert bFit

        #note that, naturally, will enforce having correct measure lines, since going across barline throughs exception

    return comp
Пример #31
0
def reverse(track, key='C'):
    # Copy value of reference to aviod problems with overwriting
    input_track = copy.deepcopy(track)
    #empty track to write to later
    reversed_track = Track()
    b = Bar(key)
    reversed_track.add_bar(b)

    #create a reversed list of notes from input track
    input_notes = input_track.get_notes()
    reversed_notes = reversed(list(input_notes))

    #Add notes to reversed_track
    for note in reversed_notes:
        reversed_track.add_notes(note[-1], duration=note[1])

    # Return reversed track
    return reversed_track
Пример #32
0
def generate_bar(difficulty: float):
    some_bar = Bar('C', (4, 4))

    values = [
        value.whole, value.half, value.quarter,
        value.dots(value.half), value.eighth,
        value.dots(value.quarter), value.sixteenth,
        value.dots(value.eighth), value.quarter,
        value.dots(value.quarter)
    ]

    actual_values = []

    pitches = [
        Note("A", 3),
        Note("B", 3),
        Note("C", 4),
        Note("D", 4),
        Note("E", 4),
        Note("F", 4),
        Note("G", 4),
        Note("A", 4),
        Note("B", 4),
        Note("C", 5),
        Note("D", 5),
        Note("E", 5),
        Note("F", 5),
        Note("G", 5),
        Note("A", 5),
        Note("B", 5),
        Note("C", 6)
    ]

    if difficulty >= 10:
        actual_values = values
    else:
        index = math.ceil(difficulty)
        actual_values = values[0:index]

    while some_bar.place_notes(choice(pitches), choice(actual_values)):
        pass

    if not some_bar.is_full():
        some_bar.place_notes(choice(pitches), some_bar.value_left())

    return some_bar
Пример #33
0
 async def run(self):
     cbn = self.agent.get("current_bar_no")
     msg = await self.receive()
     if msg:
         if self.agent.get("notes_template").match(msg):
             if Note(msg.body.split(",")[0]).name in getattr(
                     chords, CFG.PROGRESSIONS[cbn])(CFG.SONG_KEY_SIGNATURE):
                 cmb = self.agent.get("current_melody_bar")
                 if cmb.current_beat + 1 / float(
                         msg.body.split(",")[1]) <= cmb.length:
                     cmb.place_notes(
                         msg.body.split(",")[0],
                         int(msg.body.split(",")
                             [1]))  # de momento 4 notas por barra
                     if cmb.current_beat == cmb.length:  # chechar si llena, entonces agregar a melody_track
                         mt = self.agent.get("melody_track")
                         mt.add_bar(cmb)
                         self.agent.set("melody_track", mt)
                         self.agent.set(
                             "current_melody_bar",
                             Bar(CFG.SONG_KEY_SIGNATURE,
                                 CFG.SONG_TIME_SIGNATURE))
                         self.agent.set("current_bar_no", cbn + 1)
                         print(
                             "{}: {}/{}".format(self.agent.name, cbn + 1,
                                                CFG.SONG_LENGTH)
                         )  # falta sacar con modulo, de momento es un acorde por barra
                         self.set_next_state(S_RECEIVE_CHORD)
                     else:
                         self.agent.set("current_melody_bar", cmb)
                         self.set_next_state(S_RECEIVE_NOTE)
                 else:
                     self.set_next_state(
                         S_RECEIVE_NOTE)  # Continúa en el mismo estado
             else:
                 self.set_next_state(
                     S_RECEIVE_NOTE)  # Continúa en el mismo estado
         else:
             self.set_next_state(
                 S_RECEIVE_NOTE)  # Continúa en el mismo estado
     else:
         self.set_next_state(S_RECEIVE_NOTE)  # Continúa en el mismo estado
Пример #34
0
def change_speed(track, factor, key, up=True):
    changed_track = Track()
    #if factor is 0 we return an empty track
    if (factor != 0.0):

        input_track = copy.deepcopy(track)
        input_notes = input_track.get_notes()
        b = Bar(key=key)
        changed_track.add_bar(b)

        #if we want to speed up (notespeed *= factor)
        if up:
            for note in input_notes:
                changed_track.add_notes(note[-1], int(note[1] * factor))

        #if we want to slow down (notespeed *= (1/factor))
        else:
            for note in input_notes:
                changed_track.add_notes(note[-1], int(note[1] / factor))

    return changed_track
Пример #35
0
def split_bar(bar, split_point):
    current_pos = 0
    bar_l = Bar()
    
    if 1/bar[0][1] > split_point: # if the first event crosses the split point (e.g. a conjoined rest)
        bar_l.place_notes(bar[0][2], 1/split_point)
        current_pos += split_point
        bar = [[bar[0][0], 1/(1/bar[0][1]-split_point), bar[0][2]]] + bar[1:] 
    
    while current_pos < split_point:
        bar_l.place_notes(bar[0][2], bar[0][1])
        current_pos += 1/bar[0][1]
        bar = bar[1:]
    bar_r = bar   
    bar_r = [fix_track_bar([b])[0] for b in bar_r]
    
    return bar_l, bar_r
Пример #36
0
def setup_tracks(midi_file_out=None):
    from tracks import melodies, cantus_firmus, key, meter, species, author
    # Create a composition, and add the vocal tracks to it.
    composition = Composition()
    composition.set_title('Counterpoint Exercise', '')
    composition.set_author(author, '')

    # Set up our vocal 'tracks' with the notes, key, meter defined in tracks.py
    tracks = {}
    for voice in [Soprano, Alto, Tenor, Bass]:
        if len(melodies[voice.name]):
            tracks[voice.name] = Track(instrument=voice())
            tracks[voice.name].add_bar(Bar(key=key, meter=meter))
            tracks[voice.name].name = voice.name
            for note in melodies[voice.name]:
                tracks[voice.name].add_notes(*note)
            composition.add_track(tracks[voice.name])

    if midi_file_out is not None:
        # Save the midi file!
        write_Composition(midi_file_out, composition, verbose=True)

    return composition, [], species
Пример #37
0
def setup_plotting():
    global fig
    global ax1
    global ax2
    global ax3
    global line1
    global line2
    global sheet

    fig = plt.figure(figsize=(12, 8))
    ax1 = fig.add_subplot(2, 2, 1)  # Volume
    ax2 = fig.add_subplot(2, 2, 2)  # Fourier
    ax3 = fig.add_subplot(2, 1, 2)  # Notes
    ax3.set_axis_off()

    line1, = ax1.plot(np.random.randn(CHUNK_SIZE))
    line2, = ax2.plot(np.random.randn(CHUNK_SIZE))

    b = Bar()
    bar = LilyPond.from_Bar(b)
    LilyPond.to_png(bar, "track")
    img = mpimg.imread("track.png")
    cropped_image = img[0:300, :, :]
    sheet = ax3.imshow(cropped_image, cmap='gray', interpolation='antialiased')
Пример #38
0
 def getChordOrArpeggio(self, input_bar):
     notes = input_bar.get_note_names()
     random.seed()
     chord = chords.major_triad(notes[random.randint(0,len(notes) - 1)])
     new_bar = Bar()
     #nc = NoteContainer(chord)
     #new_bar.place_notes(nc, 1)
     #return new_bar
     if(len(notes) % 2 != 0):
         #this will be a chord
         nc = NoteContainer(chord)
         new_bar.place_notes(nc, 1)
         return new_bar
     else:
         #this will be an arpeggio
         duration = 0
         print(str(len(chord)))
         for note in chord:
             if(duration == 0):
                 duration = 2
             else:
                 duration = 4
             new_bar.place_notes(note, duration)
         return new_bar
Пример #39
0
def export(melody_track, chords, key, time_sig, bpm, file):
    i = Instrument()
    i.instrument_nr = 1
    t2 = Track()
    for i in range(0, len(chords)):
        b = Bar(key, time_sig)
        if len(chords[i][0]) > 5:
            b.place_notes(None, 1)
        else:
            b.place_notes(NoteContainer(chords[i]), 1)
        t2 + b

    c = Composition()
    c.add_track(melody_track)
    c.add_track(t2)

    out_dir = 'out'

    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    mid = file.split('/')[-1]
    if os.path.exists(out_dir + '/' + mid):
        os.remove(out_dir + '/' + mid)
    MidiFileOut.write_Composition(out_dir + '/' + mid, c, bpm)

    file = out_dir + '/' + mid

    sys.argv.append('')
    sys.argv.append('')

    sys.argv[1] = "--midi-file=" + file
    sys.argv[2] = "--out-dir=" + out_dir

    midi.main()
    if os.path.exists(file):
        os.remove(file)
Пример #40
0
def generate_solo(chord_list):
	notes = []
	bars = []
	note = random.choice(chords.from_shorthand(chord_list[0]))
	note = Note(note)
	syncopate = random.randrange(1) == 0
	bar = Bar()
	duration = random.choice([4, 8, 16])
	if syncopate:
		bar.place_notes(None, duration)
	bar.place_notes(note, duration)
	notes.append(note)
	first = True
	for chord_name in chord_list:
		if first:
			beat = bar.current_beat
			first = False
		else:
			bar = Bar()
			beat = 0
		scale = generate_scale(chord_name)
		while beat < 1:
			if beat % .25 == 0:
				duration = random.choice([4, 8, 16])
			elif beat % .125 == 0:
				duration = random.choice([8, 16])
			rest = random.randrange(10) == 0 # 1/10
			if rest:
				bar.place_notes(None, duration)
			else:
				beginning = beat == 0
				stepwise = random.randrange(5) != 0 # 4/5
				leap = random.randrange(2) == 0 # 1/2
				if len(notes) >= 2:
					prev_motion = measure_motion(notes[-2], notes[-1], scale)
				else:
					prev_motion = random.choice([-1, 1])
				direction = int(math.copysign(1, prev_motion))
				resolve = False
				
				if abs(prev_motion) == 2:
					if len(notes) >= 3:
						prev2_motion = measure_motion(notes[-3], notes[-2], 
								scale)
					else:
						prev2_motion = 0
					if prev2_motion == 2:
						if random.randrange(2) == 0:
							stepwise, leap = False, False
					else:
						stepwise, leap = False, False
				elif abs(prev_motion) > 2:
					stepwise, resolve = True, True
				
				if beginning:
					chord_tones = chords.from_shorthand(chord_name)
					note = closest_note(notes[-1], chord_tones)
				elif stepwise:
					if resolve:
						interval = -direction
					else:
						interval = random.choice([direction, direction, 
								-direction])
					# 2/3 probability to continue in same direction
					if notes[-1].octave <= 3:
						interval = 1
					elif notes[-1].octave >= 5:
						interval = -1
					note = note_at_interval(notes[-1], interval, scale)
				elif leap: # (1 - 4/5) * 1/2 = 1/10
					interval = random.choice([-1, 1]) \
							* random.choice(range(3, len(scale)))
					note = note_at_interval(notes[-1], interval, scale)
				else: # outlining a chord
					interval = 2 * direction
					note = note_at_interval(notes[-1], interval, scale)
				bar.place_notes(note, duration)
				notes.append(note)
			beat = bar.current_beat
		bars.append(bar)
		print(notes)
	return bars
    def gen_midi(self, tracks_data):
        c = Composition()

        all_tracks = tracks_data["tracks_data"]
        curr_track = 0;

        for track_data in all_tracks:
            #TODO: set author, title, more specific instrument (that has a
            #range set

            data_max = max(track_data["note_data"])
            data_min = min(track_data["note_data"])

            data_dur_max = max(track_data["dur_data"])
            data_dur_min = min(track_data["dur_data"])

            data_range = data_max - data_min

            ####DURATIONS####
            midi_durs = [self.map_range(0, len(self.mapping_dur_vals) - 1,
                                   data_dur_min, data_dur_max, x, "dur")
                         for x in track_data["dur_data"]]
            midi_durs = [self.mapping_dur_vals[int(x)] for x in midi_durs]
            print "midi_durs: "
            print midi_durs

            ####PITCHES####
            midi_vals = [self.map_range(0, len(self.overall_mapping_vals) - 1,
                                   data_min, data_max, x, "notes")
                         for x in track_data["note_data"]]
            midi_vals = [self.overall_mapping_vals[int(x)] for x in midi_vals]

            print "midi_pitches: "
            print midi_vals

            for instr in self.instrs:
                t = Track()
                b = Bar()
                for index, midi_val in enumerate(midi_vals):
                    print "-----------------"
                    print "space left in bar"
                    print b.space_left()
                    if midi_val in instr["mapping_vals"]:
                        print "inserting NON-REST NOTE"
                        print "inserting NON-REST NOTE"
                        val_to_insert = Note().from_int(int(midi_val))
			print "DONE INSERTING NON-REST NOTE"
                    else:
                        print "INSERTING REST"
                        val_to_insert = None #insert rest instead

                    print "ABOUT TO INSERT"
                    dur_to_insert_1 = 1.0/((1.0/float(midi_durs[index])) * 0.99)
                    dur_to_insert_2 = 1.0/((1.0/float(midi_durs[index])) * 0.01)
                    b, insert_result_1 = self.insert_into_bar(curr_track, b, val_to_insert,
                                                         dur_to_insert_1)
                    print "trying to insert note..."
                    print insert_result_1
                    print "midi note DURATION is: "
                    print midi_durs[index]

                    if insert_result_1:
                         b, insert_result_2 = self.insert_into_bar(curr_track, b, None,
                                                         dur_to_insert_2)
                         print "trying to insert note..."
                         print insert_result_2
                         print "midi note DURATION is: "
                         print midi_durs[index]

                    if not insert_result_1:
                        if b.space_left() == 0.0:
                            print "hit edge case!!!!"
                            t.add_bar(b)
                            b = Bar()
                            b, insert_result = self.insert_into_bar(curr_track,
                                                                    b, val_to_insert, dur_to_insert_1)
                            b, insert_result = self.insert_into_bar(curr_track,
                                                                    b, None, dur_to_insert_2)
                            print "bar is now (after edge case): "
                            print b
                            continue

                        space_p = b.space_left()
                        space = 1.0/space_p
                        print "space percentage left: "
                        print space_p
                        print "note space left: "
                        print space

                        note_remainder = value.subtract(midi_durs[index], space)
                        print "note duration: "
                        print midi_durs[index]
                        print "note remainder: "
                        print note_remainder

                        print "bar before INSERTING PART 1 OF TIE: "
                        print b
                        dur_to_insert_1_space = 1.0/((1.0/float(space)) * 0.99)
                        dur_to_insert_2_space = 1.0/((1.0/float(space)) * 0.01)
                        if space <= 16.0:
                             print "NOTE IS LARGER THAN 16 NOTE"
                             b, insert_result = self.insert_into_bar(curr_track, b, val_to_insert, dur_to_insert_1_space)
                             b, insert_result = self.insert_into_bar(curr_track, b, None, 1.0/b.space_left())
                        else:
                             print "NOTE IS *NOT* LARGER THAN 16 NOTE"
                             b, insert_result = self.insert_into_bar(curr_track, b, None, space)
                        print "bar AFTER: "
                        print b
                        print "inserting part one of tie result: "
                        print insert_result
                        print "is bar full??? (IT SHOULD BE)"
                        print b.is_full()
                        t.add_bar(b)

                        b = Bar()
                        b, insert_result = self.insert_into_bar(curr_track, b, None, note_remainder)
                        print "inserting part TWO of tie result: "
                        print insert_result
                        print "bar after inserting remaining piece: "
                        print b

                    print "BAR IS NOW"
                    print b
                    #end for

                #add last bar
                if b.space_left() == 0.0:
                    t.add_bar(b)
                else:
                    #need to fill remaining space with rest
                    space_p = b.space_left()
                    space = 1.0/space_p
                    #b, insert_result = self.insert_into_bar(curr_track, b,
                    #                                        Note(None), space)
                    print "result for filling rest of last bar with rest: "
                    print insert_result
                    print "is bar full after adding rest to end of last bar??? (IT SHOULD BE)"
                    print b.is_full()
                    print "bar WITH REST is now: "
                    print b
                    t.add_bar(b)
                logger.debug("Track: ")
                logger.debug(t)
                #at very end of loop add track to composition
                c.add_track(t)

            curr_track += 1

        #write_Composition("midi_success.mid", c);
        return self.gen_midi_data(c)
Пример #42
0
from mingus.core import chords, intervals, notes, scales 
from mingus.containers import Note, NoteContainer, Bar, Track, Composition
from mingus.containers.Instrument import MidiInstrument
from mingus.midi import MidiFileOut
from improv import generate_solo
from subprocess import call

num_progressions = 4
chords_list = ['CM', 'G7', 'CM7', 'FM7', 'G7', 'Am7', 'G7', 'C#+']
chords_bars = []
for chord in chords_list:
	chord_nc = NoteContainer(chords.from_shorthand(chord))
	bar = Bar()
	bar.place_notes(chord_nc, 1)
	chords_bars.append(bar)
solo_track = Track()
chords_track = Track()
for _ in range(num_progressions):
	for bar in generate_solo(chords_list):
		solo_track.add_bar(bar)
	for bar in chords_bars:
		chords_track.add_bar(bar)

guitar = MidiInstrument()
guitar.instrument_nr = 26
solo_track.instrument = guitar

piano = MidiInstrument()
piano.instrument_nr = 0
chords_track.instrument = piano
Пример #43
0
 def set_as_split_chords(self):
     self.bars = []
     noted_chords = map(lambda x: assign_octaves(x, self.octave), self.chords)
     for ch in noted_chords:
         b = Bar(key=self.key)
         if len(ch) == 3:
             b.place_notes(ch[0], 4)
             b.place_notes(ch[2], 4)
             b.place_notes(ch[1], 4)
             b.place_notes(ch[2], 4)
         elif len(ch) == 4:
             b.place_notes(ch[0], 4)
             b.place_notes(ch[2], 4)
             b.place_notes(ch[1], 4)
             b.place_notes(ch[3], 4)
         else:
             b.place_notes(ch, 1)
         self.add_bar(b)
Пример #44
0
	def MIDI_to_Composition(self, file):
		header, track_data = self.parse_midi_file(file)

		c = Composition()
		if header[2]["fps"]:
			print "Don't know how to parse this yet"
			return c

		ticks_per_beat = header[2]["ticks_per_beat"]
		for track in track_data:
			t = Track()
			b = Bar()
			metronome = 1 # Tick once every quarter note
			thirtyseconds = 8 # 8 thirtyseconds in a quarter note
			meter = (4,4)
			key = 'C'

			for e in track:

				deltatime, event = e
				duration =  float(deltatime) / (ticks_per_beat * 4.0)
				if duration != 0.0:
					duration = 1.0 / duration

				if deltatime != 0:
					if not b.place_notes(NoteContainer(), duration):
						t + b
						b = Bar(key, meter)
						b.place_notes(NoteContainer(), duration)
						

				# note off
				if event["event"] == 8:
					if deltatime == 0:
						pass

				# note on 
				elif event["event"] == 9:
					n = Note(notes.int_to_note(event["param1"] % 12), 
						event["param1"] / 12 - 1)
					n.channel = event["channel"]
					n.velocity = event["param2"]

					if len(b.bar) > 0:
						b.bar[-1][2] + n
					else:
						b + n

				# note aftertouch
				elif event["event"] == 10:
					pass
				# controller select
				elif event["event"] == 11:
					pass
				# program change
				elif event["event"] == 12:
					i = MidiInstrument()
					i.instrument_nr = event["param1"]
					t.instrument = i

				# meta event
				elif event["event"] == 15:

					# Track name
					if event["meta_event"] == 3:
						t.name = event["data"]
					
					# Marker 
					elif event["meta_event"] == 6:
						pass

					# Cue Point
					elif event["meta_event"] == 7:
						pass

					# End of Track
					elif event["meta_event"] == 47:
						pass

					# Set tempo 
					#warning Only the last change in bpm will get saved currently
					elif event["meta_event"] == 81:
						mpqn = self.bytes_to_int(event["data"])
						bpm = 60000000 / mpqn

					# Time Signature
					elif event["meta_event"] == 88:
						d = event["data"]
						thirtyseconds = self.bytes_to_int(d[3])
						metronome = self.bytes_to_int(d[2]) / 24.0
						denom = 2 ** self.bytes_to_int(d[1])
						numer = self.bytes_to_int(d[0])
						meter = (numer, denom)
						b.set_meter(meter)

					# Key Signature
					elif event["meta_event"] == 89:
						pass

					else:
						print "Unsupported META event", event["meta_event"]

				else:
					print "Unsupported MIDI event", event

			t + b
			c.tracks.append(t)
		
		return c, bpm
Пример #45
0
from mingus.containers import Bar, Track
from mingus.containers.Instrument import MidiInstrument

fluidsynth.init("ChoriumRevA/ChoriumRevA.SF2", "alsa")

tr = lambda note: chords.triad(note, "C")

# that's stupid
# http://www.youtube.com/watch?v=5pidokakU4I

prg = [tr("C"), tr("G"), tr("A"), tr("F")]

bars = []

for chord in prg:
    b = Bar()
    b.place_notes(chord, 4)

    bars.append(b)

t = Track()


for b in bars:
    t.add_bar(b)
    

instrs = list(enumerate(MidiInstrument.names))
shuffle(instrs)

for i, name in instrs:
Пример #46
0
    def MIDI_to_Composition(self, file):
        (header, track_data) = self.parse_midi_file(file)
        c = Composition()
        if header[2]['fps']:
            print("Don't know how to parse this yet")
            return c
        ticks_per_beat = header[2]['ticks_per_beat']
        for track in track_data:
            t = Track()
            b = Bar()
            metronome = 1  # Tick once every quarter note
            thirtyseconds = 8  # 8 thirtyseconds in a quarter note
            meter = (4, 4)
            key = 'C'
            for e in track:
                (deltatime, event) = e
                duration = float(deltatime) / (ticks_per_beat * 4.0)
                if duration != 0.0:
                    duration = 1.0 / duration
                if deltatime != 0:
                    if not b.place_notes(NoteContainer(), duration):
                        t + b
                        b = Bar(key, meter)
                        b.place_notes(NoteContainer(), duration)

                if event['event'] == 8:
                    if deltatime == 0:
                        pass
                elif event['event'] == 9:

                # note on

                    n = Note(notes.int_to_note(event['param1'] % 12),
                             event['param1'] / 12 - 1)
                    n.channel = event['channel']
                    n.velocity = event['param2']
                    if len(b.bar) > 0:
                        b.bar[-1][2] + n
                    else:
                        b + n
                elif event['event'] == 10:

                # note aftertouch

                    pass
                elif event['event'] == 11:

                # controller select

                    pass
                elif event['event'] == 12:

                # program change

                    i = MidiInstrument()
                    i.instrument_nr = event['param1']
                    t.instrument = i
                elif event['event'] == 0x0f:

                # meta event Text

                    if event['meta_event'] == 1:
                        pass
                    elif event['meta_event'] == 3:

                    # Track name

                        t.name = event['data']
                    elif event['meta_event'] == 6:

                    # Marker

                        pass
                    elif event['meta_event'] == 7:

                    # Cue Point

                        pass
                    elif event['meta_event'] == 47:

                    # End of Track

                        pass
                    elif event['meta_event'] == 81:

                    # Set tempo warning Only the last change in bpm will get
                    # saved currently

                        mpqn = self.bytes_to_int(event['data'])
                        bpm = 60000000 / mpqn
                    elif event['meta_event'] == 88:

                    # Time Signature

                        d = event['data']
                        thirtyseconds = self.bytes_to_int(d[3])
                        metronome = self.bytes_to_int(d[2]) / 24.0
                        denom = 2 ** self.bytes_to_int(d[1])
                        numer = self.bytes_to_int(d[0])
                        meter = (numer, denom)
                        b.set_meter(meter)
                    elif event['meta_event'] == 89:

                    # Key Signature

                        d = event['data']
                        sharps = self.bytes_to_int(d[0])
                        minor = self.bytes_to_int(d[0])
                        if minor:
                            key = 'A'
                        else:
                            key = 'C'
                        for i in range(abs(sharps)):
                            if sharps < 0:
                                key = intervals.major_fourth(key)
                            else:
                                key = intervals.major_fifth(key)
                        b.key = Note(key)
                    else:
                        print('Unsupported META event', event['meta_event'])
                else:
                    print('Unsupported MIDI event', event)
            t + b
            c.tracks.append(t)
        return (c, bpm)
Пример #47
0
ini[random.randint(0, 8)] = True
chorus = Track(ini).generate(8, BAR_NUMBER, 4, scale=scale1, rand_length=True, time_signature=time_sig,
                             velocity=vel)

song = Composition()

trackmain = Track()
# here is where you set the actual instrument

print "Melody instrument: " + trackmain.set_instrument(instr).names[instr] + " ({})".format(instr)

s = SongGen.Song()
trackmain = s.generate(chorus, verse, bridge, trackmain.track)

# LAST BAR
b = Bar()
n = Note('C', 4)
n.set_channel(1)
b.place_notes(n, 4)

trackmain.add_bar(b)
song.add_track(trackmain)

# END MELODY #


# BEGIN HARMONY #

# setup verse
ini = [False] * 5
ini[random.randint(0, 4)] = True
Пример #48
0
    def MIDI_to_Composition(self, file):
        (header, track_data) = self.parse_midi_file(file)
        c = Composition()
        if header[2]['fps']:
            print "Don't know how to parse this yet"
            return c
        ticks_per_beat = header[2]['ticks_per_beat']

        for track in track_data:
            # this loop will gather data for all notes,
            # set up keys and time signatures for all bars
            # and set the tempo and instrument for the track.

            metronome = 1  # Tick once every quarter note
            thirtyseconds = 8  # 8 thirtyseconds in a quarter note
            step = 256.0 # WARNING: Assumes our smallest desired quantization step is a 256th note.

            meter = (4, 4)
            key = 'C'
            bar = 0
            beat = 0
            now = (bar, beat)
            b = None

            started_notes = {}
            finished_notes = {}
            b = Bar(key=key, meter=meter)
            bars = [b]

            bpm = None
            instrument = None
            track_name = None

            for deltatime, event in track:
                if deltatime != 0:
                    duration = (ticks_per_beat * 4.0) / float(deltatime)

                    dur_q = int(round(step/duration))
                    length_q = int(b.length * step)

                    o_bar = bar
                    c_beat = beat + dur_q
                    bar += int(c_beat / length_q)
                    beat = c_beat % length_q

                    while o_bar < bar:
                        o_bar += 1
                        o_key = b.key
                        b = Bar(key=key, meter=meter)
                        b.key = o_key
                        bars.append(b)

                    now = (bar, beat)

                if event['event'] == 8:
                # note off
                    channel = event['channel']
                    note_int = event['param1']
                    velocity = event['param2']
                    note_name = notes.int_to_note(note_int % 12)
                    octave = note_int / 12 - 1

                    note = Note(note_name, octave)
                    note.channel = channel
                    note.velocity = velocity

                    x = (channel, note_int)
                    start_time = started_notes[x]
                    del started_notes[x]
                    end_time = now

                    y = (start_time, end_time)
                    if y not in finished_notes:
                        finished_notes[y] = []

                    finished_notes[y].append(note)

                elif event['event'] == 9:
                # note on
                    channel = event['channel']
                    note_int = event['param1']
                    velocity = event['param2']
                    x = (channel, note_int)

                    # add the note to the current NoteContainer
                    started_notes[x] = now

                elif event['event'] == 10:
                # note aftertouch
                    pass

                elif event['event'] == 11:
                # controller select
                    pass

                elif event['event'] == 12:
                # program change
                # WARNING: only the last change in instrument will get saved.
                    i = MidiInstrument()
                    i.instrument_nr = event['param1']
                    instrument = i

                elif event['event'] == 0x0f:
                # meta event Text
                    if event['meta_event'] == 1:
                        pass

                    elif event['meta_event'] == 3:
                    # Track name
                        track_name = event['data']

                    elif event['meta_event'] == 6:
                    # Marker
                        pass

                    elif event['meta_event'] == 7:
                    # Cue Point
                        pass

                    elif event['meta_event'] == 47:
                    # End of Track
                        pass

                    elif event['meta_event'] == 81:
                    # Set tempo
                    # WARNING: Only the last change in bpm will get saved
                        mpqn = self.bytes_to_int(event['data'])
                        bpm_o = bpm
                        bpm = 60000000 / mpqn

                    elif event['meta_event'] == 88:
                    # Time Signature
                        d = event['data']
                        thirtyseconds = self.bytes_to_int(d[3])
                        metronome = self.bytes_to_int(d[2]) / 24.0
                        denom = 2 ** self.bytes_to_int(d[1])
                        numer = self.bytes_to_int(d[0])
                        meter = (numer, denom)
                        b.set_meter(meter)

                    elif event['meta_event'] == 89:
                    # Key Signature
                        d = event['data']
                        sharps = self.bytes_to_int(d[0])
                        minor = self.bytes_to_int(d[0])
                        if minor:
                            key = 'A'
                        else:
                            key = 'C'
                        for i in xrange(abs(sharps)):
                            if sharps < 0:
                                key = intervals.major_fourth(key)
                            else:
                                key = intervals.major_fifth(key)
                        b.key = Note(key)

                    else:
                        print 'Unsupported META event', event['meta_event']

                else:
                    print 'Unsupported MIDI event', event

            t = Track(instrument)
            t.name = track_name

            sorted_notes = {}

            # sort the notes (so they are added to the bars in order)
            # this loop will also split up notes that span more than one bar.
            for x in finished_notes:
                (start_bar, start_beat), (end_bar, end_beat) = x
                if end_beat == 0:
                    end_bar -= 1
                    end_beat = int(bars[end_bar].length * step)

                while start_bar <= end_bar:
                    nc = NoteContainer(finished_notes[x])
                    b = bars[start_bar]

                    if start_bar < end_bar:
                        # only executes when note spans more than one bar.
                        length_q = int(b.length * step)
                        dur = int(step/(length_q - start_beat))
                    else:
                        # always executes - add the final section of this note.
                        dur = int(step/(end_beat-start_beat))

                    if start_beat != 0:
                        at = float(start_beat)/step
                    else:
                        at = 0.0

                    if start_bar not in sorted_notes:
                        sorted_notes[start_bar] = {}
                    if at not in sorted_notes[start_bar]:
                        sorted_notes[start_bar][at] = (dur, nc)

                    # set our offsets for the next loop
                    start_beat = 0
                    start_bar += 1

            # add all notes to all bars in order.
            for start_bar in sorted(sorted_notes.keys()):
                for at in sorted(sorted_notes[start_bar].keys()):
                    dur, nc = sorted_notes[start_bar][at]
                    bars[start_bar].place_notes_at(nc, dur, at)

            # add the bars to the track, in order
            for b in bars:
                b.fill_with_rests()
                t + b

            # add the track to the composition
            c.tracks.append(t)

        return (c, bpm)