Пример #1
0
class MainWidget2(BaseWidget):
    def __init__(self):
        super(MainWidget2, self).__init__()

        # create a clock and a tempo map
        self.clock = Clock()
        self.tempo_map = SimpleTempoMap(120)

        # and text to display our status
        self.label = topleft_label()
        self.add_widget(self.label)

    def on_key_down(self, keycode, modifiers):
        if keycode[1] == 'c':
            self.clock.toggle()

    def on_update(self):

        time = self.clock.get_time()
        tick = self.tempo_map.time_to_tick(time)
        bpm = self.tempo_map.get_tempo()

        self.label.text = 'time:{:.2f}\n'.format(time)
        self.label.text += tick_str(tick) + '\n'
        self.label.text += 'bpm:{}\n'.format(bpm)
        self.label.text += 'c: toggle clock\n'
Пример #2
0
class MainWidget4(BaseWidget):
    def __init__(self):
        super(MainWidget4, self).__init__()

        self.audio = Audio(2)
        self.synth = Synth('../data/FluidR3_GM.sf2')
        self.audio.set_generator(self.synth)

        # create clock, tempo_map, scheduler
        self.clock = Clock()
        self.tempo_map = SimpleTempoMap(120)
        self.sched = Scheduler(self.clock, self.tempo_map)

        # create the metronome:
        self.metro = Metronome(self.sched, self.synth)

        # and text to display our status
        self.label = topleft_label()
        self.add_widget(self.label)

    def on_key_down(self, keycode, modifiers):
        if keycode[1] == 'c':
            self.clock.toggle()

        if keycode[1] == 'm':
            self.metro.toggle()

        bpm_adj = lookup(keycode[1], ('up', 'down'), (10, -10))
        if bpm_adj:
            new_tempo = self.tempo_map.get_tempo() + bpm_adj
            self.tempo_map.set_tempo(new_tempo, self.sched.get_time())

    def on_update(self):
        # scheduler and audio get poked every frame
        self.sched.on_update()
        self.audio.on_update()

        bpm = self.tempo_map.get_tempo()

        self.label.text = self.sched.now_str() + '\n'
        self.label.text += 'Metronome:' + ("ON" if self.metro.playing else
                                           "OFF") + '\n'
        self.label.text += 'tempo:{}\n'.format(bpm)
        self.label.text += 'm: toggle Metronome\n'
        self.label.text += 'up/down: change speed\n'
Пример #3
0
class MainWidget3(BaseWidget):
    def __init__(self):
        super(MainWidget3, self).__init__()

        # create a clock and TempoMap
        self.clock = Clock()
        self.tempo = SimpleTempoMap(120)

        # create a Scheduler
        self.sched = Scheduler(self.clock, self.tempo)

        # and text to display our status
        self.label = topleft_label()
        self.add_widget(self.label)

        # to see accumulated output:
        self.output_text = ''

    def on_key_down(self, keycode, modifiers):
        if keycode[1] == 'c':
            self.clock.toggle()

        if keycode[1] == 'a':
            now = self.sched.get_tick()
            later = now + (2 * kTicksPerQuarter)
            self.output_text += "now={}. post at tick={}\n".format(now, later)
            self.cmd = self.sched.post_at_tick(self._do_it, later, 'hello')

        if keycode[1] == 'b':
            self.sched.remove(self.cmd)

    def _do_it(self, tick, msg):
        self.output_text += "{} (at {})\n".format(msg, tick)

    def on_update(self):
        # scheduler gets called every frame to process events
        self.sched.on_update()
        self.label.text = self.sched.now_str() + '\n'
        self.label.text += 'c: toggle clock\n'
        self.label.text += 'a: post event\n'
        self.label.text += 'b: remove event\n'
        self.label.text += self.output_text
Пример #4
0
class TempoCursorHandler(object):
    """
    Handles the TempoCursor GUI.
    Also stores and updates all currently active TempoCursors.
    """
    def __init__(self,
                 norm,
                 sandbox,
                 mixer,
                 client,
                 client_id,
                 block_handler,
                 tempo=60):
        self.norm = norm
        self.module_name = 'TempoCursor'
        self.sandbox = sandbox
        self.mixer = mixer
        self.client = client
        self.cid = client_id
        self.block_handler = block_handler

        self.tempo = tempo
        self.clock = Clock()
        self.tempo_map = SimpleTempoMap(bpm=self.tempo)

        self.touch_points = {}

        self.cursors = AnimGroup()
        self.sandbox.add(self.cursors)

        self.gui = CursorGUI(norm,
                             pos=self.norm.nt((20, 300)),
                             beat_callback=self.update_touch_points)

        self.delete_mode = {}

    def on_touch_down(self, cid, pos):
        if cid == self.cid:
            self.gui.on_touch_down(pos)

        if not self.sandbox.in_bounds(pos):
            return

        for cursor in self.cursors.objects:
            cursor_pos = (cursor.pos[0] - cursor.size[0] / 2,
                          cursor.pos[1] - cursor.size[1] / 2)
            if in_bounds(pos, cursor_pos, cursor.size):
                if self.delete_mode[cid]:
                    self.cursors.objects.remove(cursor)
                    self.cursors.remove(cursor)
                    return

        if self.delete_mode[cid]:
            return

        touch_points = self.touch_points[cid]

        if len(touch_points) == 0:
            return
        cursor = TempoCursor(self.norm, pos, self.tempo,
                             self.clock, self.tempo_map,
                             copy.deepcopy(touch_points), self.block_handler)
        self.cursors.add(cursor)

    def on_touch_move(self, cid, pos):
        pass

    def on_touch_up(self, cid, pos):
        pass

    def on_key_down(self, cid, key):
        if key == 'p':
            self.clock.toggle()
        if key == 'v' and cid == self.cid:
            self.delete_mode[cid] = not self.delete_mode[cid]
            self.update_server_state(post=True)
        if key == 'up':
            self.tempo += 4
            self.tempo_map.set_tempo(self.tempo)
            self.update_server_state(post=True)
        if key == 'down':
            self.tempo -= 4
            self.tempo_map.set_tempo(self.tempo)
            self.update_server_state(post=True)

    def on_update(self):
        self.cursors.on_update()

    def update_touch_points(self, touch_points):
        self.touch_points[self.cid] = touch_points
        self.update_server_state(post=True)

    def display_controls(self):
        cur_time = self.clock.get_time()
        cur_tick = self.tempo_map.time_to_tick(cur_time)
        info = 'delete mode: {}\n\n'.format(self.delete_mode[self.cid])
        info += 'tempo: {}\n'.format(self.tempo)
        return info

    def update_server_state(self, post=False):
        """Update server state. If post is True, relay this updated state to all clients."""
        state = {
            'touch_points': self.touch_points,
            'delete_mode': self.delete_mode,
            'tempo': self.tempo
        }
        data = {
            'module': self.module_name,
            'cid': self.cid,
            'state': state,
            'post': post
        }
        self.client.emit('update_state', data)

    def update_client_state(self, cid, state):
        """Update this handler's state."""
        if cid != self.cid:  # this client already updated its own state
            self.touch_points = state['touch_points']
            self.delete_mode = state['delete_mode']
            self.tempo = state['tempo']

    def sync_state(self, state):
        """
        Initial sync with the server's copy of module state.
        """
        self.touch_points = state['touch_points']
        self.delete_mode = state['delete_mode']
        self.tempo = state['tempo']

        # after initial sync, add default values for this client
        self.touch_points[self.cid] = []
        self.delete_mode[self.cid] = False

        # update server with these default values
        # post=True here because we want all other clients' states to update with this client's
        # default values.
        self.update_server_state(post=True)