Esempio n. 1
0
 def copy_event(event):
     if type(event) is SetTempoEvent:
         new_event = SetTempoEvent()
         new_event.tick = event.tick
         new_event.data[0] = event.data[0]
         new_event.data[1] = event.data[1]
         new_event.data[2] = event.data[2]
         return new_event
     elif type(event) is NoteOnEvent:
         new_event = NoteOnEvent()
         new_event.tick = event.tick
         new_event.channel = event.channel
         new_event.data[0] = event.data[0]
         new_event.data[1] = event.data[1]
         return new_event
     elif type(event) is NoteOffEvent:
         new_event = NoteOffEvent()
         new_event.tick = event.tick
         new_event.channel = event.channel
         new_event.data[0] = event.data[0]
         new_event.data[1] = event.data[1]
         return new_event
     elif type(event) is ProgramChangeEvent:
         new_event = ProgramChangeEvent
         new_event.tick = event.tick
         new_event.channel = event.channel
         new_event.data[0] = event.data[0]
         return new_event
     else:
         raise ('Not Supported')
Esempio n. 2
0
 def add_note_on_abs(track,
                     pitch,
                     start,
                     loudness,
                     channel,
                     resolution=default_resolution):
     on = NoteOnEvent(tick=int(resolution * start),
                      channel=channel,
                      velocity=loudness,
                      pitch=pitch)
     track.append(on)
     return track
Esempio n. 3
0
    def to_midi(self):
        """
        Constructs a L{MIDI EventStream<midi.EventStream>} from the 
        data in this stream.
        This can then be output to a file to be played.
        
        Note that TPCNotes will be output as normal MIDI notes. We 
        can't do anything of the clever tuning stuff that we can do 
        with tonal space coordinates, since we'd need to do a further 
        step of analysis to work out the fully specified TS point from 
        the pitch class.
        
        """
        tempo = 120

        from midi import EventStream, NoteOffEvent, NoteOnEvent, SetTempoEvent
        mid = EventStream()
        mid.add_track()
        # Set the tempo first at the beginning
        temp = SetTempoEvent()
        temp.tempo = tempo
        temp.tick = 0
        mid.add_event(temp)
        # Work out how many ticks there are in a millisecond
        ticks_per_ms = float(mid.resolution) * tempo / 60000
        # Create midi events for every event in our stream
        for ev in self.events:
            if isinstance(ev, TPCNoteEvent):
                # Create note-on and note-off events
                note = ev.note

                noteon = NoteOnEvent()
                noteon.pitch = note
                noteon.tick = int(ev.start * ticks_per_ms)
                noteon.velocity = 100
                mid.add_event(noteon)

                noteoff = NoteOffEvent()
                noteoff.pitch = note
                noteoff.tick = int(ev.end * ticks_per_ms)
                noteoff.velocity = 100
                mid.add_event(noteoff)
            elif isinstance(ev, (ChordEvent, BeatEvent)):
                # These events don't affect the midi data
                continue
            else:
                raise TypeError, "event type %s not recognised by "\
                    "MIDI converter." % type(ev).__name__
        return mid
Esempio n. 4
0
def tonal_space_note_events(coord,
                            start,
                            duration,
                            origin_note=60,
                            velocity=100):
    """
    Creates the MIDI events needed to play the given tonal space 
    coordinate. These will be a single-note tuning event (to retune 
    the appropriate note), a note-on event and a note-off event.
    
    @type coord: tuple
    @param coord: 3D tonal space coordinate
    @type start: int
    @param start: start time of note in ticks
    @type duration: int
    @param duration: length of the note in ticks
    @type origin_note: int
    @param origin_note: midi note number to assume the origin of the 
      tonal space is equal to in pitch (default 60, middle C)
    @rtype: tuple
    @return: (tuning event, note on event, note off event)
    
    """
    # Work out what note to retune for the root and how
    change = tonal_space_tuning(coord)
    note = change[0]

    # Create the tuning event
    tuning = single_note_tuning_event([change])
    tuning.tick = start
    # Play the note
    note_on = NoteOnEvent()
    note_on.pitch = note
    note_on.velocity = velocity
    note_on.tick = start
    # Stop the note
    note_off = NoteOffEvent()
    note_off.pitch = note
    note_off.tick = start + duration
    note_off.velocity = velocity

    return (tuning, note_on, note_off)
Esempio n. 5
0
    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
Esempio n. 6
0
    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