Exemplo n.º 1
0
 def clear(self):
     for i in range(36, 100):
         if not GameThread.button_to_xy(i) in self.parts:
             self.outport.send(
                 Message(type="note_on",
                         channel=0,
                         note=i,
                         velocity=33,
                         time=0))
Exemplo n.º 2
0
def test_translate_and_send1(mappings_bank1):
    store.update('mappings', mappings_bank1)
    store.update('active_bank', 0)

    midi = Message(type='note_on', channel=0, note=11, velocity=0)
    ret = get_translations(process_midi(midi))
    assert len(ret) == 0

    store.update('active_bank', 1)

    midi = Message(type='note_on', channel=2, note=33, velocity=0)
    ret = get_translations(process_midi(midi))
    assert len(ret) == 1

    ret = translate_and_send(ret[0])
    assert ret['type'] == midi.type
    assert int(ret['channel']) == midi.channel + 1
    assert int(ret['control']) == midi.note
Exemplo n.º 3
0
def reconstruct(filename, sequence, tpb, subdivisions=2):
    mid = MidiFile()
    track = MidiTrack()
    mid.tracks.append(track)
    mid.ticks_per_beat = tpb

    for note in sequence:
        tone, velocity, length = note

        track.append(Message('note_on', note=tone, velocity=velocity, time=0))
        track.append(
            Message('note_off',
                    note=tone,
                    velocity=0,
                    time=length * int(tpb / subdivisions)))

    mid.save('output/' + filename)
    return mid
Exemplo n.º 4
0
    def midify_note(self, signal):
        if(signal['type'] != 'note'):
            print('Error when midifying note')
            return '', ''

        noteNumber = noteToNumber[signal['note_name']]
        length = int(self.ticks_per_beat * self.timesig[0] * signal['length_num'] / signal['length_denom'])
        length = int(self.ticks_per_beat * self.timesig[1] * signal['length_num'] / signal['length_denom'])
        return Message('note_on', note=noteNumber, channel=self.current_track, velocity=self.dynamic, time=0), Message('note_off',note=noteNumber, channel=self.current_track, velocity=self.dynamic, time=length)
Exemplo n.º 5
0
 def next_bar(self, piece: Piece) -> Iterable[Message]:
     barlen = barlength(piece.beatsperbar, piece.bpm)
     for i in range(piece.beatsperbar):
         time = (i + 0.5) / piece.beatsperbar * barlen
         yield Message(type="note_on",
                       note=61,
                       channel=9,
                       velocity=50,
                       time=time)
Exemplo n.º 6
0
def note_to_message(tpb: int, channel: int, note: MidiNote, last_delta: int) \
        -> Generator[Message, None, None]:
    # one beat is a quarter note, time is in whole notes
    time_conv_factor = tpb / 0.25
    if note.note != -1:
        yield Message('note_on',
                      channel=channel,
                      note=note.note,
                      time=last_delta)
        yield Message('note_off',
                      channel=channel,
                      note=note.note,
                      time=int(note.time * time_conv_factor))
    else:
        yield Message('note_off',
                      channel=channel,
                      note=0,
                      time=int(note.time * time_conv_factor))
Exemplo n.º 7
0
 def _noteOff(self, noteOnMsg):
     # Instead of a note_off message, CSound requires a note_on with v=0.
     # I have absolutely no idea why.
     self._track.append(
         Message('note_on',
                 note=noteOnMsg.note,
                 velocity=0,
                 time=noteOnMsg.time,
                 channel=noteOnMsg.channel))
Exemplo n.º 8
0
def to_mido_track(
    track: Track,
    channel: Optional[int] = None,
    use_note_off_message: bool = False,
) -> MidiTrack:
    """Return a Track object as a mido MidiTrack object.

    Parameters
    ----------
    track : :class:`muspy.Track` object
        Track object to convert.
    use_note_off_message : bool, optional
        Whether to use note-off messages. If False, note-on messages
        with zero velocity are used instead. The advantage to using
        note-on messages at zero velocity is that it can avoid sending
        additional status bytes when Running Status is employed.
        Defaults to False.
    channel : int, optional
        Channel number. Defaults to 10 for drums and 0 for other
        instruments.

    Returns
    -------
    :class:`mido.MidiTrack` object
        Converted mido MidiTrack object.

    """
    if channel is None:
        channel = 9 if track.is_drum else 0

    # Create a new MIDI track
    midi_track = MidiTrack()

    # Track name messages
    if track.name is not None:
        midi_track.append(MetaMessage("track_name", name=track.name))

    # Program change messages
    midi_track.append(
        Message("program_change", program=track.program, channel=channel))

    # Note on and note off messages
    for note in track.notes:
        midi_track.extend(
            to_mido_note_on_note_off(
                note,
                channel=channel,
                use_note_off_message=use_note_off_message,
            ))

    # End of track message
    midi_track.append(MetaMessage("end_of_track"))

    # Convert to delta time
    to_delta_time(midi_track)

    return midi_track
Exemplo n.º 9
0
    def create_track(self):
        track = MidiTrack()
        offset_added = False

        track.append(
            MetaMessage('set_tempo', tempo=bpm2tempo(self.tempo_bpm), time=0))
        for msg in self.original_track:
            if not offset_added and hasattr(msg, 'note'):
                track.append(
                    Message('note_on',
                            note=100,
                            velocity=1,
                            time=self.offset_ticks))
                track.append(Message('note_off', note=100, velocity=1, time=0))
                offset_added = True
            track.append(msg)

        return track
Exemplo n.º 10
0
def postprocess(numpy_array):
    log("Creating midi")
    multiplier = 5
    length = int(Args.clocks_per_click * multiplier) * 2
    midi_time_interval = update_quantization_values()
    assert numpy_array.shape == (Args.max_octave_range * 12,
                                 Args.beats_per_sample *
                                 len(midi_time_interval))

    track = []
    column_times = []
    for beat_number in range(Args.beats_per_sample):
        for a in midi_time_interval:
            column_times.append(
                int((a + beat_number * Args.clocks_per_click * 4) *
                    multiplier))

    prev_column_time = 0
    for column_number in range(numpy_array.shape[1]):
        for row_number in range(numpy_array.shape[0]):
            if numpy_array[row_number, column_number]:
                start_point = column_times[column_number] - prev_column_time
                track.append(['note_on', row_number, start_point])
                prev_column_time = column_times[column_number]

    i = 0
    while True:
        message = track[i]
        if message[0] == 'note_on':
            extra_time = length
            for second_index in range(i + 1, len(track)):
                msg2 = track[second_index]
                if extra_time > msg2[2]:  # =?
                    extra_time -= msg2[2]
                else:
                    track[second_index][2] -= extra_time
                    track.insert(second_index,
                                 ['note_off', message[1], extra_time])
                    break
                track.append(['note_off', message[1], extra_time])
        i += 1
        if i >= len(track):
            break

    mid = MidiFile()
    miditrack = MidiTrack()
    mid.tracks.append(miditrack)
    for message in track:
        assert message[1] >= 0 and message[2] >= 0
        miditrack.append(
            Message(message[0],
                    note=60 + message[1],
                    velocity=99,
                    time=message[2]))

    mid.save(datetime.datetime.now().strftime(Args.output_file) + '_' +
             str(random.randint(0, 1000)) + '.mid')
Exemplo n.º 11
0
 def add_meta_info(self):
     tempo = mido.bpm2tempo(self.bpm)
     numerator = Fraction(self.time_signature).numerator
     denominator = Fraction(self.time_signature).denominator
     super().append(MetaMessage('time_signature', numerator=numerator, denominator=denominator))
     super().append(MetaMessage('set_tempo', tempo=tempo, time=0))
     super().append(MetaMessage('key_signature', key=self.key))
     for channel, program in self.instruments.items():
         super().append(Message('program_change', channel=int(channel), program=program, time=0))
Exemplo n.º 12
0
 def create_key_note(note_val: int, note_on: bool):
     if self.menu.is_menu_active(Menus.GAME):
         note_name = "note_on"
         if note_on == False:
             note_name = "note_off"
         new_note = Message(note_name)
         new_note.note = note_val
         new_note.velocity = 100
         self.devices.input_messages.append(new_note)
Exemplo n.º 13
0
 def activate_layer(self, layer, send_active=True):
     #print "Switching to layer %d" % layer
     for i in range(0, 5):
         if i != layer:
             self.outport.send(
                 Message('note_off',
                         channel=self.midi_channel,
                         note=self.midi_cmds_layer[i],
                         velocity=0))
     if send_active == True:
         self.outport.send(
             Message('note_on',
                     channel=self.midi_channel,
                     note=self.midi_cmds_layer[layer],
                     velocity=127))
     if self.state.active_layer != layer:
         self.refresh_channels(layer)
         self.state.active_layer = layer
Exemplo n.º 14
0
def renderblocks_write(presses = ''):
   myfont = pygame.font.Font(None, 30)
   global port
   global sentnotes
   global prevNote
   global ctr
   global keybrightness
   screen.fill((0,0,0))
   bluespace = pygame.rect.Rect(0,screenh*0.5,screenw,screenh/7)
   if keybrightness > 100:
       keybrightness -= 10
   pygame.draw.rect(screen, (keybrightness,keybrightness,255), bluespace)
   keylen = [100,80,60,40,20,40,60,80,100,120]
   keylen = [120,100,80,60,40,20,40,60,80,100]
   for key in range(10):
       pygame.draw.rect(screen, (100,100,100), ((key+1)*screenw*0.075+50, 0, screenw*0.025, screenh-keylen[key]))
       p = myfont.render(str(key+1),1,(200,200,255))
       screen.blit(p,((key+1)*screenw*0.075+50,screenh*0.75))
   for note in sentnotes:
       pygame.draw.circle(screen, (255,255,255), note.center, screenw/70)
       note.y-=5

   ctr += 1
   if presses != '':
       keybrightness = 255
       #if presses == 0:
       #    presses = 10
       #write(mapping.keys()[mapping.values().index(presses)],ctr)
       #ctr = 0
       if prevNote != '':
           write(prevNote,ctr)
           print ctr
           ctr = 0
           print ctr
       ctr = 0
       sentnotes.append(pygame.rect.Rect(presses*screenw*0.075+50, screenh*0.75, screenw*0.025, screenh*0.033))
       print presses
       prevNote = mapping.keys()[mapping.values().index(presses)]
       for ch in [0,1,2,4,9]:
           port.send(Message('note_on', note = mapping.keys()[mapping.values().index(presses)], velocity = 127, time = 0))
       #port.send(Message('note_off', note = mapping.keys()[mapping.values().index(presses)]+2, velocity = 100, time = 32))
       for ch in [0,1,2,4,9]:
           port.send(Message('note_off', note = mapping.keys()[mapping.values().index(presses)], velocity = 100, time = 500))
   pygame.display.update()
Exemplo n.º 15
0
def haptic_action():
    with mido.open_output(midi_interface) as outport:
        while 1:

            key = stdscr.getch()
            if key == ord('f'):
                msg = Message('note_on',
                              channel=CHAN,
                              note=MHP_ACT_IND + NOTE_F,
                              velocity=2)
                outport.send(msg)
                print('action Flex, velocity 2')
            if key == ord('o'):
                msg = Message('note_off',
                              channel=CHAN,
                              note=MHP_ACT_IND + NOTE_F,
                              velocity=2)
                outport.send(msg)
                print('stop action flex')
            if key == ord('e'):
                msg = Message('note_on',
                              channel=CHAN,
                              note=MHP_ACT_IND + NOTE_E,
                              velocity=50)
                outport.send(msg)
                print('action Extension, velocity 50')
            if key == ord('a'):
                msg = Message('note_on',
                              channel=CHAN,
                              note=MHP_ACT_IND + NOTE_A,
                              velocity=20)
                outport.send(msg)
                print(
                    'action impulse inwards, threshold 20 for stopping the impulse'
                )
            if key == ord('q'):
                print(
                    'action impulse outwards, threshold 20 for stopping the impulse'
                )
                msg = Message('note_off',
                              channel=CHAN,
                              note=MHP_ACT_IND + NOTE_A,
                              velocity=20)
                outport.send(msg)
Exemplo n.º 16
0
def main():
    pitch_chooser = chooser.PitchChooser(60)
    octave_chooser = chooser.NumberChooser(1, 3)
    length_chooser = chooser.LengthChooser()
    velocity_chooser = chooser.VelocityChooser()
    pitch_mod_1 = modulator.SineMod(800)
    pitch_mod_2 = modulator.SineMod(2200)
    pitch_mod = modulator.CombinedMod([pitch_mod_1, pitch_mod_2], [1, 1])
    octave_mod_rnd = modulator.RandMod()
    octave_mod_snh = modulator.SampleHoldMod(timing.note_time(1/4))
    octave_mod = modulator.ValueMod(octave_mod_snh, octave_mod_rnd)
    #pitch_mod_1 = RandMod()
    #pitch_mod = SampleHoldMod(note_time(1/2))
    length_mod = modulator.TriangleMod(800)
    velocity_mod = modulator.SineMod(220)
    mid = MidiFile()
    track = MidiTrack()
    mid.tracks.append(track)

    track.append(Message('program_change', program=12, time=0))

    time = 0
    bars = 4

    while time < timing.note_time(4 * bars):
        len_mod_val = length_mod.value(time)
        note_length = length_chooser.choose_length(len_mod_val)

        #ptc_mod_val = pitch_mod.value(time, pitch_mod_1.value(time))
        ptc_mod_val = pitch_mod.value(time)
        #oct_mod_val = octave_mod.value(time)
        #octave = octave_chooser.choose(oct_mod_val)
        octave = 3
        pitch = pitch_chooser.choose_pitch(ptc_mod_val, octave)

        vel_mod_val = velocity_mod.value(time)
        velocity = velocity_chooser.choose_velocity(vel_mod_val)

        track.append(Message('note_on', note=pitch, velocity=velocity, time=0))
        track.append(Message('note_off', note=pitch, velocity=velocity, time=note_length))
        time += note_length

    mid.save('new_song.mid')
Exemplo n.º 17
0
def tapsToMidi(taps,
               tempo=60,
               pitch=60,
               velocity=100,
               resolution=4,
               time_signature=(4, 4),
               key_signature="C"):
    """Converts Taps to Midi Format (Rhythyms -> Sheet Music)
    @param taps: an array of tuples containing the time a note occurs and the length of the note (both in ticks)
    @param tempo: number of beats per minute
    @param pitch: the note to use when converting the rhythyms to sheet music (expressed using midi numbers)
    @param key_signature: String expressing the key signature the sheet music will be in (usually the same note as the pitch)
    @param time_signature: tuple containing numerator first, denominator seconds
    @param velocity: loudness of the note, expressed using MIDI convention
    """

    track = MidiTrack()

    track.append(MetaMessage('key_signature', key=key_signature))
    track.append(
        MetaMessage('time_signature',
                    numerator=time_signature[0],
                    denominator=time_signature[1]))
    track.append(MetaMessage('set_tempo', tempo=bpm2tempo(tempo)))

    (_, duration) = taps[0]
    track.append(Message('note_on', note=pitch, velocity=velocity, time=0))
    track.append(
        Message('note_off', note=pitch, velocity=velocity, time=duration))

    for i in range(1, len(taps)):
        (current_time, duration) = taps[i]
        (last_time, last_duration) = taps[i - 1]
        from_last = current_time - (last_time + last_duration)
        track.append(
            Message('note_on', note=pitch, velocity=velocity, time=from_last))
        track.append(
            Message('note_off', note=pitch, velocity=velocity, time=duration))

    midi = MidiFile(ticks_per_beat=resolution)
    midi.tracks.append(track)

    return midi
Exemplo n.º 18
0
    def play(self, port, tempo: int) -> None:
        """
        Provided a valid Midi port, send the notes in sequence to that port in real
        time (i.e. however long the current `sequence` is, is how long this will take
        to run.

        :param port: Open Mido Port object
        :param tempo: Speed to play Midi notes
        """
        for seq in self.sequence:
            if isinstance(seq, Note):
                on = Message('note_on', note=seq.value)
                port.send(on)
                time.sleep(pulses_to_seconds(seq.duration, tempo))
                off = Message('note_off', note=seq.value)
                port.send(off)

            elif isinstance(seq, Rest):
                time.sleep(pulses_to_seconds(seq.duration))
Exemplo n.º 19
0
def generateRandomNotes():
    try:
        with mido.open_output('Python App', autoreset=True,
                              virtual=True) as port:
            print('Using {}'.format(port))
            while True:
                note = random.choice(notes)

                on = Message('note_on', note=note, channel=0)
                print('Sending {}'.format(on))
                port.send(on)
                time.sleep(0.05)

                off = Message('note_off', note=note, channel=0)
                print('Sending {}'.format(off))
                port.send(off)
                time.sleep(0.1)
    except KeyboardInterrupt:
        pass
Exemplo n.º 20
0
 def _instrument_change(self,
                        track: MidiTrack,
                        channel: int = 0,
                        instrument: int = 0,
                        time: int = 0):
     track.append(
         Message("program_change",
                 channel=channel,
                 program=instrument,
                 time=time))
Exemplo n.º 21
0
 def instrument(self, instrument):
     if isinstance(instrument, dict):
         self.octave_shift = instrument.get('octave_shift', 0)
         instrument = instrument['midi_number']
     self._instrument = instrument
     self.append(
         Message(
             'program_change',
             program=instrument - 1,  # is it just Mido that counts from 0?
             channel=self.channel))
Exemplo n.º 22
0
def set_chord(track, notes, sec_per_tick):
    #times_in_ticks = [n.position_in_sec / sec_per_tick for n in notes] #genuine
    times_in_ticks = [0 for n in notes]

    for ix, note in enumerate(notes):
        time_delta_in_ticks = int(times_in_ticks[ix] -
                                  (times_in_ticks[ix - 1] if ix > 0 else 0))
        track.append(
            Message('note_on',
                    note=note.value,
                    velocity=note.velocity,
                    time=max(time_delta_in_ticks - note.duration, 0)))

    for note in notes:
        track.append(
            Message('note_off',
                    note=note.value,
                    velocity=note.velocity,
                    time=note.duration))
Exemplo n.º 23
0
def send_midi_message(midi, channel, out_port):
    # select note
    note = midi_to_note_on_scale(midi)

    # turn on note
    on = Message('note_on', channel=channel, note=note, velocity=int(midi))
    out_port.send(on)

    ms = 10000 / midi

    # log and sleep
    logging.debug("lenght:" + str(ms) + "ms velocity:" + str(midi) + " note:" +
                  str(note) + " thread:" +
                  str(threading.currentThread().getName()))
    time.sleep(ms / 1000.0)

    # turn off note
    off = Message('note_off', channel=channel, note=note, velocity=int(midi))
    out_port.send(off)
Exemplo n.º 24
0
 def __init__(self, channel=0, instrument=Piano.AcousticGrandPiano):
     super(MidiTrack, self).__init__()
     self.__append = super(MidiTrack, self).append
     self.instrument = instrument
     self.channel = channel
     self.append(
         Message('program_change',
                 program=instrument,
                 time=0,
                 channel=self.channel))
Exemplo n.º 25
0
    def random(self, channel, scale, track, time_factor=60):

        sum = 0
        while sum < self.time_limit and not scale is None:
            note = random.choice(scale)
            time = abs(
                random.randrange(2 * time_factor, 8 * time_factor,
                                 time_factor))

            if (sum + time >= self.time_limit):
                time = self.time_limit - sum
                sum = self.time_limit
            else:
                sum += time
            track.append(
                Message('note_on',
                        note=note,
                        channel=channel,
                        velocity=60,
                        time=time))
            track.append(
                Message('note_off',
                        note=note,
                        channel=channel,
                        velocity=60,
                        time=time))

        # fill with empty
        remaining_time = int(self.time_limit - sum)
        track.append(
            Message('note_on',
                    note=0,
                    channel=channel,
                    velocity=0,
                    time=remaining_time))
        track.append(
            Message('note_off',
                    note=0,
                    channel=channel,
                    velocity=0,
                    time=remaining_time))

        return self.outfile
Exemplo n.º 26
0
 def _turn_off_notes(midi_track, channel, tick, prev_tick, notes_to_turn_off,  # pylint: disable=dangerous-default-value
                     notes_to_ignore=[]):
     """Create add MIDI messages to turn off all given notes except those in the ignore list."""
     for pitch in notes_to_turn_off:
         if pitch not in notes_to_ignore:
             delta = tick - prev_tick
             prev_tick = tick
             midi_track.append(Message('note_off', channel=channel, note=pitch,
                                       velocity=0, time=delta))
     return prev_tick
Exemplo n.º 27
0
def Chord(root, duration, track, list_beat, velocity):
    root = root - 12
    #velocity = [1,1,1,1,1,1,1,1]
    chrod_note = [root, root + 7, root + 12]
    track.append(Message('control_change', channel=0, control=64, value=127))
    for i in range(len(list_beat)):
        durationtime = int(list_beat[i] / 2 * duration)
        track.append(
            Message('note_on',
                    note=root,
                    velocity=velocity[i] * (rd.randrange(-20, 20) + 40),
                    time=0))
        track.append(
            Message('note_off', note=root, velocity=127, time=durationtime))
        # track.append(Message('note_on', note=root, velocity=rd.randrange(-20, 20) + 40, time=32))
        # track.append(Message('note_off', note=root, velocity=127, time=2))
        # track.append(Message('note_on', note=root, velocity=rd.randrange(-20, 20) + 40, time=32))
        # track.append(Message('note_off', note=root, velocity=127, time=2))
    track.append(Message('control_change', channel=0, control=64, value=0))
Exemplo n.º 28
0
def write_midi_mono(mono_notes, midi_file_name):

    midi_file = MidiFile(ticks_per_beat=10000)

    track = MidiTrack()
    midi_file.tracks.append(track)

    track.append(Message('program_change', program=12, time=0))

    cur_time = 0
    prev_note = None
    for i, note in enumerate(mono_notes):

        cur_time += 0.005

        if note == prev_note:
            continue

        else:
            cur_ticks = second2tick(cur_time, midi_file.ticks_per_beat,
                                    default_tempo)

            # If silence, don't write note on and off messages to midi
            if prev_note != 88 and prev_note is not None:
                track.append(
                    Message('note_off',
                            note=int(bottom_note + prev_note),
                            velocity=127,
                            time=int(cur_ticks)))
                cur_time = 0
                cur_ticks = 0

            if note != 88 and i != len(mono_notes) - 1:
                track.append(
                    Message('note_on',
                            note=int(bottom_note + note),
                            velocity=127,
                            time=int(cur_ticks)))
                cur_time = 0

            prev_note = note

    midi_file.save(midi_file_name)
Exemplo n.º 29
0
def midier(z, q, instnum, inst, setting):
    from mido import MidiFile, MidiTrack, Message
    mid = MidiFile()
    track = MidiTrack()
    mid.tracks.append(track)
    track.append(Message('program_change', program=instnum, time=0))
    track.append(Message('control_change', control=7, value=100))

    if setting == 'rests':
        chain = 0
        for i in range(len(z)):
            if q[i] == 'r':
                chain += z[i]
                if i == len(z) - 1:
                    track.append(
                        Message('note_on', note=60, velocity=0, time=chain))
            else:
                track.append(
                    Message('note_on', note=q[i], velocity=63, time=chain))
                track.append(
                    Message('note_on', note=q[i], velocity=0, time=z[i]))
                chain = 0
        mid.save(''.join([inst, '.mid']))
    else:
        chain = 0
        for i in range(len(z)):
            if q[i] == 'r':
                chain += z[i]
                if i == len(z) - 1:
                    track.append(
                        Message('note_on',
                                note=track[-1].__dict__['note'],
                                velocity=0,
                                time=chain))
            else:
                if i == 0:
                    track.append(
                        Message('note_on', note=q[i], velocity=63, time=0))
                else:
                    track.append(
                        Message('note_on',
                                note=track[-1].__dict__['note'],
                                velocity=0,
                                time=chain))
                    track.append(
                        Message('note_on', note=q[i], velocity=63, time=0))
                    chain = z[i]
        mid.save(''.join([inst, '.mid']))
Exemplo n.º 30
0
def transform(srtz: Iterator[Subtitle], is_lyrics: bool) -> MidiFile:
    out = MidiFile(charset=getdefaultencoding(), ticks_per_beat=TICKS_PER_BEAT)
    track = MidiTrack()
    out.tracks.append(track)

    timeof = lambda dt: int(dt.total_seconds() * SEC_MS)
    t0 = 0
    for srt in srtz:
        t1 = timeof(srt.start)
        t2 = timeof(srt.end)
        if is_lyrics:  #v const branches
            track.append(MetaMessage("lyrics", text=srt.content, time=t1 - t0))
        note = NOTE_BASE if is_lyrics else int(srt.content)  #< pitch from
        track.append(
            Message("note_on", note=note, time=0 if is_lyrics else t1 - t0))
        track.append(Message("note_off", note=note, time=t2 - t1))
        t0 = t2

    return out