def generate(self, overlay=None, offset=0): """ Generates a midi stream. """ octaves = 1 if overlay is not None: stream = overlay # Use organ sound instrument = 23 # Find the last channel used in the file we're overlaying channel = max(ev.channel for ev in stream.trackpool) + 1 volume = 50 else: stream = EventStream() stream.resolution = self.resolution # Just use piano instrument = 0 channel = 0 volume = 127 stream.add_track() pc = ProgramChangeEvent() pc.value = instrument pc.tick = 0 pc.channel = channel stream.add_event(pc) # Length of each chord in midi ticks chord_length = int(self.resolution * self.chord_length) times = [i * chord_length + offset for i in range(len(self.labels))] pending_note_offs = [] for label, time in zip(self.labels, times): chord_root = label.root # Work out the notes for this chord triad_notes = [(chord_root + note) % (octaves*12) + 72 for \ note in self.chord_vocab[label.label]] # Add the root in the octave two below triad_notes.append(chord_root + 48) # Add note offs for notes already on for noff in pending_note_offs: noff.tick = time - 1 stream.add_event(noff) pending_note_offs = [] if self.text_events: # Add a text event to represent the chord label tevent = LyricsEvent() tevent.data = "%s\n" % label tevent.tick = time stream.add_event(tevent) # Add a note-on and off event for each note for note in triad_notes: non = NoteOnEvent() non.tick = time non.pitch = note non.channel = channel non.velocity = volume stream.add_event(non) # Hold the note until the next chord is played noff = NoteOffEvent() noff.pitch = note noff.channel = channel noff.velocity = volume pending_note_offs.append(noff) # Add the last remaining note offs for noff in pending_note_offs: noff.tick = time + chord_length stream.add_event(noff) return stream
def generate(self, overlay=None, offset=0): """ Generates a midi stream. """ octaves = 1 if overlay is not None: stream = overlay # Use organ sound instrument = 23 # Find the last channel used in the file we're overlaying channel = max(ev.channel for ev in stream.trackpool) + 1 volume = 30 else: stream = EventStream() stream.resolution = self.resolution # Just use piano instrument = 0 channel = 0 volume = 127 stream.add_track() pc = ProgramChangeEvent() pc.value = instrument pc.tick = 0 pc.channel = channel stream.add_event(pc) # Length of each chord in midi ticks chord_length = int(self.resolution * self.chord_length) if self.times is None: times = [ i * chord_length + offset for i in range(len(self.labels)) ] else: times = [t + offset for t in self.times] formatter = getattr(self, 'formatter') pending_note_offs = [] for (tonic, mode, chord), time in zip(self.labels, times): scale_chord_root = constants.CHORD_NOTES[mode][chord][0] chord_root = (tonic + scale_chord_root) % 12 triad_type = constants.SCALE_TRIADS[mode][chord] # Work out the notes for this chord triad_notes = [(chord_root + note) % (octaves * 12) + 72 for note in constants.TRIAD_NOTES[triad_type]] # Add the root in the octave two below triad_notes.append(chord_root + 48) # Add note offs for notes already on for noff in pending_note_offs: noff.tick = time - 1 stream.add_event(noff) pending_note_offs = [] if self.text_events: # Add a text event to represent the chord label tevent = LyricsEvent() label = formatter((tonic, mode, chord)) tevent.data = "%s\n" % label tevent.tick = time stream.add_event(tevent) # Add a note-on and off event for each note for note in triad_notes: non = NoteOnEvent() non.tick = time non.pitch = note non.channel = channel non.velocity = volume stream.add_event(non) # Hold the note until the next chord is played noff = NoteOffEvent() noff.pitch = note noff.channel = channel noff.velocity = volume pending_note_offs.append(noff) # Add the last remaining note offs for noff in pending_note_offs: noff.tick = time + chord_length stream.add_event(noff) return stream
def generate(self, overlay=None, offset=0): """ Generates a midi stream. """ octaves = 1 if overlay is not None: stream = overlay # Use organ sound instrument = 23 # Find the last channel used in the file we're overlaying channel = max(ev.channel for ev in stream.trackpool) + 1 volume = 50 else: stream = EventStream() stream.resolution = self.resolution # Just use piano instrument = 0 channel = 0 volume = 127 stream.add_track() pc = ProgramChangeEvent() pc.value = instrument pc.tick = 0 pc.channel = channel stream.add_event(pc) # Length of each chord in midi ticks chord_length = int(self.resolution * self.chord_length) times = [i*chord_length + offset for i in range(len(self.labels))] pending_note_offs = [] for label,time in zip(self.labels, times): chord_root = label.root # Work out the notes for this chord triad_notes = [(chord_root + note) % (octaves*12) + 72 for \ note in self.chord_vocab[label.label]] # Add the root in the octave two below triad_notes.append(chord_root + 48) # Add note offs for notes already on for noff in pending_note_offs: noff.tick = time-1 stream.add_event(noff) pending_note_offs = [] if self.text_events: # Add a text event to represent the chord label tevent = LyricsEvent() tevent.data = "%s\n" % label tevent.tick = time stream.add_event(tevent) # Add a note-on and off event for each note for note in triad_notes: non = NoteOnEvent() non.tick = time non.pitch = note non.channel = channel non.velocity = volume stream.add_event(non) # Hold the note until the next chord is played noff = NoteOffEvent() noff.pitch = note noff.channel = channel noff.velocity = volume pending_note_offs.append(noff) # Add the last remaining note offs for noff in pending_note_offs: noff.tick = time+chord_length stream.add_event(noff) return stream
def generate(self, overlay=None, offset=0): """ Generates a midi stream. """ octaves = 1 if overlay is not None: stream = overlay # Use organ sound instrument = 23 # Find the last channel used in the file we're overlaying channel = max(ev.channel for ev in stream.trackpool) + 1 volume = 30 else: stream = EventStream() stream.resolution = self.resolution # Just use piano instrument = 0 channel = 0 volume = 127 stream.add_track() pc = ProgramChangeEvent() pc.value = instrument pc.tick = 0 pc.channel = channel stream.add_event(pc) # Length of each chord in midi ticks chord_length = int(self.resolution * self.chord_length) if self.times is None: times = [i*chord_length + offset for i in range(len(self.labels))] else: times = [t+offset for t in self.times] formatter = getattr(self, 'formatter') pending_note_offs = [] for (tonic,mode,chord),time in zip(self.labels, times): scale_chord_root = constants.CHORD_NOTES[mode][chord][0] chord_root = (tonic+scale_chord_root) % 12 triad_type = constants.SCALE_TRIADS[mode][chord] # Work out the notes for this chord triad_notes = [(chord_root + note) % (octaves*12) + 72 for note in constants.TRIAD_NOTES[triad_type]] # Add the root in the octave two below triad_notes.append(chord_root + 48) # Add note offs for notes already on for noff in pending_note_offs: noff.tick = time-1 stream.add_event(noff) pending_note_offs = [] if self.text_events: # Add a text event to represent the chord label tevent = LyricsEvent() label = formatter((tonic,mode,chord)) tevent.data = "%s\n" % label tevent.tick = time stream.add_event(tevent) # Add a note-on and off event for each note for note in triad_notes: non = NoteOnEvent() non.tick = time non.pitch = note non.channel = channel non.velocity = volume stream.add_event(non) # Hold the note until the next chord is played noff = NoteOffEvent() noff.pitch = note noff.channel = channel noff.velocity = volume pending_note_offs.append(noff) # Add the last remaining note offs for noff in pending_note_offs: noff.tick = time+chord_length stream.add_event(noff) return stream