Exemplo n.º 1
0
    def test_unreferenced_cleanup(self):
        """Test that the player gets cleaned up if there are no references left to it
        and playback of contained sources has finished."""
        silence = Silence(.1)
        player = Player()
        player_id = id(player)

        @player.event
        def on_player_eos():
            on_player_eos.called = True
        on_player_eos.called = False

        player.queue(silence)
        player.play()
        player = None

        while not on_player_eos.called:
            time.sleep(.1)

        gc.collect()

        for obj in gc.get_objects():
            if isinstance(obj, Player) and id(obj) == player_id:
                self.fail('Player should be cleaned up')
        self.assertListEqual([], gc.garbage, msg='Should not find garbage')
def real_playsound():
    sound = pyglet.media.load('mt.wav')
    player = Player()
    player.queue(sound)
    player.eos_action = player.EOS_LOOP
    player.play()
    pyglet.app.run()
Exemplo n.º 3
0
def play_sound_effect(name: str, volume: float = 1.0):
    """Play a sound effect."""
    player = Player()
    player.queue(load(f'{ASSETS}audio/{name}.wav'))
    player.volume = volume * settings.get_sfx_volume()
    player.play()
    sfxs.append(player)
Exemplo n.º 4
0
 def playEffect(self, soundName):
     if not self.enabled:
         return
     soundName = soundName.lower()
     snd = self.getSound(soundName)
     assert snd
     p = Player()
     p.volume = self.soundEffectVolume
     p.queue(snd)
     p.play()
Exemplo n.º 5
0
 def playEffect(self, soundName):
     if not self.enabled:
         return
     soundName = soundName.lower()
     snd = self.getSound(soundName)
     assert snd
     p = Player()
     p.volume = self.soundEffectVolume
     p.queue(snd)
     p.play()
Exemplo n.º 6
0
def on_key_press(symbol, modifiers):
	p = Player()

	p.queue(drums[symbol])
	in_q.put(None)
	v = out_q.get(block=True)[1]
	print v
	p.volume = v
	print p.volume
	p.play()
def main():
    director.init(**window)
    main_scene = Scene(StartLayer())

    player = Player()
    player.queue(load("resources/audios/cave.wav"))
    player.eos_action = player.EOS_LOOP
    player.play()

    director.run(main_scene)
 def play_sound_once(self,soundfile,volume):
     if self.config.sound_switch>0:
         play_sound = Player()
         play_sound_source = load(soundfile)
         play_sound_group = SourceGroup(play_sound_source.audio_format, None)
         play_sound_group.loop = False
         play_sound_group.queue(play_sound_source)
         play_sound.queue(play_sound_group)
         play_sound.volume=float(volume) * self.config.sound_switch
         play_sound.play()
Exemplo n.º 9
0
def main():
    director.init(**window)
    main_scene = Scene(StartLayer())

    player = Player()
    player.queue(load("resources/audios/cave.wav"))
    player.eos_action = player.EOS_LOOP
    player.play()

    director.run(main_scene)
Exemplo n.º 10
0
class DisplayTitle(Layer):
    display_pos_size = {"display_title": {"X": 0, "Y": 0, "W": 1, "H": 1}}

    def __init__(self):
        Layer.__init__(self)
        self.config = Config()
        self.gallery = Gallery()
        self.wind = Player()
        source = load("music/sound_start.wav")
        self.wind.queue(source)
        self.wind.volume = 0.3
        self.wind.play()
        self.background = Sprite(self.gallery.content["display"]["title"])
        self.optimal_scale = (self.config.window_width *
                              self.display_pos_size["display_title"]["W"]
                              ) / self.background.width
        self.background.image_anchor = 0, 0
        self.background.scale = self.optimal_scale
        self.background.x = self.config.window_width * self.display_pos_size[
            "display_title"]["X"]
        self.background.y = self.config.window_height * self.display_pos_size[
            "display_title"]["Y"]
        self.left_margin = self.background.x
        self.bottom_margin = self.background.y
        self.optimal_width = self.background.width
        self.optimal_height = self.background.height

        place_holder_image = Sprite(self.gallery.content["screen"]["title"])
        place_holder_image.position = director.window.width / 2, director.window.height / 2
        #place_holder_image.scale=self.optimal_scale/30
        #place_holder_image.do(ScaleBy(45, duration=35))
        place_holder_image.scale = self.optimal_scale
        self.add(place_holder_image)
        self.background2 = self.background
        self.add(self.background)
        self.add(self.background2)
        self.schedule_interval(self.intro_train_start, interval=5)
        self.schedule_interval(self.intro_music_start, interval=4)
        self.is_event_handler = True

    def on_mouse_press(self, x, y, buttons, modifiers):
        self.wind.pause()
        self.unschedule(self.intro_music_start)
        self.unschedule(self.intro_train_start)
        events.emit_show_mainmenu()

    def intro_music_start(self, event):
        director.core.switch_intro_music(True)
        self.unschedule(self.intro_music_start)

    def intro_train_start(self, event):
        self.background.do(FadeOut(duration=20))
        self.unschedule(self.intro_train_start)
Exemplo n.º 11
0
def playFile(sound, reps=1):
    import pyglet
    from pyglet.media import Player

    player = Player()
    song = pyglet.media.load(sound, streaming=False)
    for i in range(reps):
        player.queue(song)

    player.play()

    def callback(dt):
        pyglet.app.exit()

    pyglet.clock.schedule_once(callback, song.duration * reps)
    pyglet.app.run()
Exemplo n.º 12
0
class AudioEngine:
    """A high level audio engine for easily playing SFX and Music."""
    def __init__(self, channels=5):
        self.sfx_players = deque([Player() for _ in range(channels)],
                                 maxlen=channels)
        self.music_player = Player()

    def set_volume(self, percentage):
        """Set the audio volume, as a percentage of 1 to 100.

        :param percentage: int: The volume, as a percentage.
        """
        volume = max(min(1, percentage / 100), 0)
        for player in self.sfx_players:
            player.volume = volume
        self.music_player.volume = volume

    def play(self, source, position=(0, 0, 0)):
        """Play a sound effect on the next available channel

        :param source: A pyglet audio Source
        :param position: Optional spacial position for the sound.
        """
        player = self.sfx_players[0]
        player.position = position
        player.queue(source=source)
        if not player.playing:
            player.play()
        else:
            player.next_source()
        self.sfx_players.rotate()

    def play_music(self, source):
        """Play a music track, or switch to a new one.

        :param source: A pyglet audio Source
        """
        self.music_player.queue(source=source)
        if not self.music_player.playing:
            self.music_player.play()
        else:
            self.music_player.next_source()
Exemplo n.º 13
0
def play(audio):
    if audio != "silent":
        player1 = Player()
        player1.queue(load(join(DATA, "chronotank.ogg")))
        player1.queue(load(join(DATA, "imagine_a_world.ogg")))
        player1.play()

        player2 = Player()
        player2.eos_action = Player.EOS_LOOP
        player2.queue(load(join(DATA, "stupidsongimadenofarting.ogg")))
        player2.play()
Exemplo n.º 14
0
class Task(ColorLayer, pyglet.event.EventDispatcher):
    
    d = Dispatcher()
    
    states = ["INIT", "CALIBRATE", "IGNORE_INPUT", "TASK", "DONE"]
    STATE_INIT = 0
    STATE_CALIBRATE = 1
    STATE_IGNORE_INPUT = 2
    STATE_TASK = 3
    STATE_DONE = 4
    
    BG_TILE_SIZE = (1024,128)
    FG_TILE_SIZE = (1024,128)
    
    is_event_handler = True
    
    def __init__(self, client=None):
        self.screen = director.get_window_size()
        super(Task, self).__init__(0, 0, 0, 255, 1024, int(768*1.1))
        self.client = client
        self.state = self.STATE_INIT
        
        self.mole_images = [resource.image('mole_1.png'),
                            resource.image('mole_laugh1.png'),
                            resource.image('mole_laugh2.png'),
                            resource.image('mole_laugh3.png'),
                            resource.image('mole_thump1.png'),
                            resource.image('mole_thump2.png'),
                            resource.image('mole_thump3.png'),
                            resource.image('mole_thump4.png')]
        
        self.music = Player()
        self.music.queue(pyglet.resource.media('whack.mp3'))
        self.music.eos_action = 'loop'
        
        self.cm = CollisionManagerBruteForce()
        
        self.moles = []
        for i in range(0,3):
            mole = Mole(self.mole_images, (112 + (i * 310)), (127-80))
            self.moles.append(mole)
            self.add(mole, 55)
            self.cm.add(mole)
        for i in range(3,6):
            mole = Mole(self.mole_images, (112 + ((i-3) * 310)), (383-80))
            self.moles.append(mole)
            self.add(mole, 35)
            self.cm.add(mole)
        for i in range(6,9):
            mole = Mole(self.mole_images, (112 + ((i-6) * 310)), (639-80))
            self.moles.append(mole)
            self.add(mole, 15)
            self.cm.add(mole)
            
        self.text_batch = BatchNode()
        self.add(self.text_batch, z=100)
        
        self.score = 0
            
        scorey = int((768 + int(768*1.1))/2)
        self.score_num = text.Label("%06d" % self.score, font_name="Score Board", font_size=48, x=512, y=scorey, color=(255, 255, 255, 255),
                                    anchor_x='center', anchor_y='center', batch=self.text_batch.batch)
                                            
        self.fix = Label('G', font_name='Cut Outs for 3D FX', font_size=48,
                          position=(0,0), color=(255, 0, 0, 192), anchor_x='center', anchor_y='center')
        self.fix.visible = False
        self.add(self.fix, z=100000)

        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,0)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,128)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,256)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,384)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,512)))
        self.add(Sprite(resource.image('bg_dirt128.png'), anchor=(0,0), position=(0,640)))
        
        self.add(Sprite(resource.image('grass_lower128.png'), anchor=(0,0), position=(0,0)), z=60)
        self.add(Sprite(resource.image('grass_upper128.png'), anchor=(0,0), position=(0,128)), z=50)
        self.add(Sprite(resource.image('grass_lower128.png'), anchor=(0,0), position=(0,256)), z=40)
        self.add(Sprite(resource.image('grass_upper128.png'), anchor=(0,0), position=(0,384)), z=30)
        self.add(Sprite(resource.image('grass_lower128.png'), anchor=(0,0), position=(0,512)), z=20)
        self.add(Sprite(resource.image('grass_upper128.png'), anchor=(0,0), position=(0,640)), z=10)
        
        
    def set_score(self):
        self.score_num.begin_update()
        self.score_num.text = "%06d" % self.score
        self.score_num.end_update()
        
    def visit(self):
        super(Task, self).visit()
        if director.settings["overlay"]:
            for mole in self.moles:
                if mole.opacity > -1:
                    if mole.state == 1:
                        color = (.3,0.0,0.0,.7)
                    else:
                        color = (.3,0.2,0.5,.7)
                    p = Polygon([(mole.center[0]-mole.rx, mole.center[1]-mole.ry), 
                                 (mole.center[0]+mole.rx, mole.center[1]-mole.ry),
                                 (mole.center[0]+mole.rx, mole.center[1]+mole.ry),
                                 (mole.center[0]-mole.rx, mole.center[1]+mole.ry)],
                                color=color)
                    p.render()
        
    def mole_up(self):
        moles = [mole for mole in self.moles if not mole.active]
        if moles:
            random.choice(moles).up()
        
    def animate(self, dt):
        self.mole_up()
        if random.randint(0, 3) == 0:
            self.mole_up()
                    
    def game_over(self):
        self.state = self.STATE_GAME_OVER
        
    def clear(self):
        self.music.pause()
        self.music.seek(0)
        for mole in self.moles:
            mole.active = False
            mole.state = 0
            mole.position = mole.position_in
        pyglet.clock.unschedule(self.animate)
        if self.client:
            self.client.removeDispatcher(self.d)
            self.client.stopDataStreaming()
            self.client.stopFixationProcessing()
        
    def reset(self):
        self.clear()
        if self.client:
            self.client.addDispatcher(self.d)
            #self.client.setDataFormat('%TS %ET %SX %SY %DX %DY %EX %EY %EZ')
            #self.client.startDataStreaming()
            self.client.startFixationProcessing()
        self.state = self.STATE_TASK
        self.score = 0
        pyglet.clock.schedule_interval(self.animate, .5)
        self.music.play()
        
    def on_enter(self):
        if isinstance(director.scene, TransitionScene): return
        super(Task, self).on_enter()
        
        if director.settings['eyetracker']:
            self.state = self.STATE_CALIBRATE
            self.dispatch_event("start_calibration", self.calibration_ok, self.calibration_bad)
        else:
            self.reset()
            
    def calibration_ok(self):
        self.dispatch_event("stop_calibration")
        self.reset()
        
    def calibration_bad(self):
        self.dispatch_event("stop_calibration")
        director.scene.dispatch_event("show_intro_scene")
        
    def on_exit(self):
        if isinstance(director.scene, TransitionScene): return
        super(Task, self).on_exit()
        self.clear()

    @d.listen('ET_FIX')
    def iViewXEvent(self, inResponse):
        if inResponse[0] == 'l':
            x = int(float(inResponse[2]))
            y = int(float(inResponse[3]))
            if director.settings["overlay"]:
                self.fix.position = (x, y)
                self.fix.visible = True
            self.handle_mouse_press(x, y)
    
    @d.listen('ET_EFX')
    def iViewXEvent(self, inResponse):
        if inResponse[0] == 'l':
            if director.settings["overlay"]:
                self.fix.visible = False
    
    @d.listen('ET_SPL')
    def iViewXEvent(self, inResponse):
        pass
        
    def handle_mouse_press(self, x, y):
        for obj in self.cm.objs_touching_point(x, y):
            if obj.active:
                if obj.state == 0:
                    obj.state = 1
                    obj.thump()
                    self.score += 10
                elif obj.state == 2:
                    self.score -= 10
                self.set_score()
        
    def on_mouse_press(self, x, y, buttons, modifiers):
        posx, posy = director.get_virtual_coordinates(x, y)
        self.handle_mouse_press(posx, posy)

    def on_mouse_motion(self, x, y, dx, dy):
        pass
        
    def on_key_press(self, symbol, modifiers):
        if self.state < self.STATE_IGNORE_INPUT: return
        if symbol == key.W and (modifiers & key.MOD_ACCEL):
            director.scene.dispatch_event("show_intro_scene")
            True
        if self.state == self.STATE_TASK:
            pass
        elif self.state == self.STATE_DONE:
            pass
Exemplo n.º 15
0
class Gui(object):
    def __init__(self, manager, win, debug=False):
        self.manager = manager
        self.debug = debug
        #self.lab=Label(win, text="Serial port:")
        #self.lab.place(x=30, y=20)
        #self.txtfld=Entry(win, text="Serial port")
        #self.txtfld.place(x=300, y=20)
        #self.btn_cnct=Button(win, text="Connect printer", command=self.connect)
        #self.btn_cnct.place(x=30, y=50)
        #self.btn_init=Button(win, text="Initialize", command=self.initialize, state=DISABLED)
        #self.btn_init.place(x=30, y=90)

        #self.tidal_vol=("300","400","500","750","900","1000")
        #self.lab_tv=Label(win, text='Tidal volume:')
        #self.lab_tv.place(x=30, y=180)
        #self.tv=Combobox(win, values=self.tidal_vol)
        #self.tv.place(x=240, y=180)

        #self.resp_rate=("12","16","20","32")
        #self.lab_rr=Label(win, text='Respiratory rate:')
        #self.lab_rr.place(x=30, y=210)
        #self.rr=Combobox(win, values=self.resp_rate)
        #self.rr.place(x=240, y=210)

        #self.insp_exp=("1:2")
        #self.lab_ie=Label(win, text='Inspiratory/expiratory:')
        #self.lab_ie.place(x=30, y=240)
        #self.ie=Combobox(win, values=self.insp_exp)
        #self.ie.place(x=240, y=240)

        #self.btn_run=Button(win, text="Run Ventilation", command=self.start_run,state=DISABLED)
        #self.btn_run.place(x=30, y=310)
        #self.btn_stop=Button(win, text="Stop",command=self.stop,state=DISABLED)
        #self.btn_stop.place(x=180, y=310)

        self.readings = []
        self.state = None

        self.reading_pressure = Label(win,
                                      text="Latest pressure (cmH2O)",
                                      font=("Helvetica", 18))
        self.reading_pressure.place(x=30, y=20)
        self.reading_ppeak = Label(win,
                                   text="Latest PPeak (cmH2O)",
                                   font=("Helvetica", 18))
        self.reading_ppeak.place(x=35, y=50)
        self.reading_timestamp = Label(win,
                                       text="Latest reading age (seconds)")
        self.reading_timestamp.place(x=30, y=90)
        self.reading_sample_rate = Label(win, text="Sample Rate")
        self.reading_sample_rate.place(x=30, y=110)
        self.reading_pressure_inches = Label(win,
                                             text="Latest pressure (inH2O)")
        self.reading_pressure_inches.place(x=30, y=130)
        self.exit_button = Button(win,
                                  text="Close App",
                                  command=self.exit_application)
        self.exit_button.place(x=460, y=1)

        Thread(target=self.timestampDisplayThread, args=[]).start()

        self.pressure_options = [i for i in range(0, PRESSURE_UPPER_LIMIT + 1)]
        self.max_alarm_enabled = BooleanVar(False)
        self.min_alarm_enabled = BooleanVar(False)
        self.timeout_alarm_enabled = BooleanVar(False)
        self.timeout_alarm_enabled.set(True)

        self.min_alarm_enabled_checkbox = makeCheckbox(
            win, "Enabled Min Pressure Alarm", self.min_alarm_enabled)
        self.min_alarm_enabled_checkbox.place(x=30, y=160)
        self.min_alarm_threshold_label = Label(win,
                                               text="Minimum Pressure (cmH2O)")
        self.min_alarm_threshold_label.place(x=30, y=220)
        self.min_alarm_threshold_input = Combobox(win,
                                                  values=self.pressure_options)
        self.min_alarm_threshold_input.current(0)
        self.min_alarm_threshold_input.place(x=30, y=240)
        self.min_alarm_interval_label = Label(win,
                                              text="Alarm Interval (seconds)")
        self.min_alarm_interval_label.place(x=30, y=265)
        self.min_alarm_interval_input = Combobox(win, values=INTERVAL_LABELS)
        self.min_alarm_interval_input.current(0)
        self.min_alarm_interval_input.place(x=30, y=285)

        self.max_alarm_enabled_checkbox = makeCheckbox(
            win, "Enabled Max Pressure Alarm", self.max_alarm_enabled)
        self.max_alarm_enabled_checkbox.place(x=280, y=160)
        self.max_alarm_threshold_label = Label(win,
                                               text="Maximum Pressure (cmH2O)")
        self.max_alarm_threshold_label.place(x=280, y=220)
        self.max_alarm_threshold_input = Combobox(win,
                                                  values=self.pressure_options)
        self.max_alarm_threshold_input.current(len(self.pressure_options) - 31)
        self.max_alarm_threshold_input.place(x=280, y=240)
        self.max_alarm_interval_label = Label(win,
                                              text="Alarm Interval (seconds)")
        self.max_alarm_interval_label.place(x=280, y=265)
        self.max_alarm_interval_input = Combobox(win, values=INTERVAL_LABELS)
        self.max_alarm_interval_input.current(0)
        self.max_alarm_interval_input.place(x=280, y=285)

        self.timeout_alarm_enabled_checkbox = makeCheckbox(
            win, "Enabled Lost Signal Alarm", self.timeout_alarm_enabled)
        self.timeout_alarm_enabled_checkbox.place(x=30, y=320)
        self.timeout_alarm_interval_label = Label(
            win, text="Lost Signal Timeout (seconds)")
        self.timeout_alarm_interval_label.place(x=30, y=380)
        self.timeout_alarm_interval_input = Combobox(win,
                                                     values=TIMEOUT_LABELS)
        self.timeout_alarm_interval_input.current(0)
        self.timeout_alarm_interval_input.place(x=30, y=400)

        self.test_alarm = Button(win,
                                 text="Test Alarm",
                                 command=self.test_alarm)
        self.test_alarm.place(x=285, y=365)
        self.clear_alarm = Button(win,
                                  text="Clear Alarm",
                                  command=self.clear_alarm)
        self.clear_alarm.place(x=285, y=395)

        self.alarm_active = False
        self.alarm_messages = []
        self.alarms_messages_var = StringVar()
        self.alarms_messages_label = Label(
            win, textvariable=self.alarms_messages_var, font=("Helvetica", 32))
        self.alarms_messages_label.place(x=30, y=440)
        self.alarms_messages_label['bg'] = 'lightgrey'
        self.alarms_messages_label['fg'] = 'red'

        self.player = None
        self.last_seek = datetime.now()
        Thread(target=self.pygletThread, args=[]).start()
        Thread(target=self.alarmThread, args=[]).start()

        #TODO
        #self.place_dropdown(win,'Tidal volume:', self.tidal_vol, 60, 180)
        #self.place_dropdown(win,'Respiratory rate:', self.resp_rate, 60, 210)
        #self.place_dropdown(win,'Inspiratory/expiratory:', self.insp_exp, 60, 240)
        #self.place_btn(win,"Run ventilation", self.run,60,290)
        #self.place_btn(win,"Stop", self.run,180,290)

        #3dpav control
        self.printer = None
        self.lookup = None
        self.started_run = False
        self._isOk = False

        self.window = win

    def exit_application(self):
        self.manager.shutdown()

    def shutdown(self):
        self.window.destroy()

    def boot(self):
        self.window.title('3DPaV Pressure Monitor')
        self.window.geometry("529x564+0+0")
        self.window.mainloop()

    def pygletThread(self):
        self.player = Player()
        source = pyglet.resource.media('red_alert.wav')
        self.player.queue(source)
        pyglet.app.run()

    def timestampDisplayThread(self):
        while True:
            self.ui_updater_func()
            time.sleep(0.01)

    def test_alarm(self):
        self.add_alarm("Test Alarm")

    def clear_alarm(self):
        self.alarm_active = False
        self.alarm_messages = []
        self.alarms_messages_label['bg'] = 'lightgrey'
        self.window['bg'] = 'lightgrey'

    def add_alarm(self, alarm_message):
        self.alarm_active = True
        self.alarm_messages = list(set(self.alarm_messages + [alarm_message]))
        self.alarms_messages_label['bg'] = 'white'
        self.window['bg'] = 'red'

    def alarmThread(self):
        while True:
            now = datetime.now()
            if ((now - self.last_seek).total_seconds() > LOOP_TIMEOUT_SECONDS):
                self.player.seek(0)
                self.last_seek = now
            if (self.player):
                if (self.alarm_active):
                    if not self.player.playing:
                        print('START ALERT')
                        self.player.play()
                else:
                    if self.player.playing:
                        print('STOP ALERT')
                        self.player.pause()
            time.sleep(0.01)

    def updateReadings(self, state):
        self.readings.append(
            Reading(state['latestPressureValue'], state['timestamp']))
        self.state = state

    def ui_updater_func(self):
        state = self.state
        if state is None:
            return
        timestamp = state['timestamp']
        latestPressureValue = state['latestPressureValue']
        latestPPeakValue = state['latestPPeakValue']
        sampleRate = state['sampleRate']

        self.reading_pressure.configure(
            text="Latest Pressure (cmH2O): {:10.2f}".format(
                latestPressureValue))
        self.reading_pressure_inches.configure(
            text="Latest Pressure (inH2O): {:10.2f}".format(
                latestPressureValue / INCHES_TO_CENIMETERS))
        self.reading_ppeak.configure(
            text="Latest PPeak (cmH2O):    {:10.2f}".format(latestPPeakValue))
        self.reading_sample_rate.configure(
            text="Sample Rate (ms): {:10.2f}".format(sampleRate * 1000))
        self.alarms_messages_var.set(", \n".join(self.alarm_messages))

        now = datetime.now()
        min_alarm_label = self.min_alarm_interval_input.get()
        max_alarm_label = self.max_alarm_interval_input.get()
        min_alarm_interval = INTERVAL_OPTIONS_MAP[min_alarm_label]
        max_alarm_interval = INTERVAL_OPTIONS_MAP[max_alarm_label]
        self.readings = [
            r for r in self.readings
            if ((now - r.stamp).total_seconds() < (2 * MAX_INTERVAL_VALUE))
        ]

        trigger_max_alert = False
        if (self.max_alarm_enabled.get()):
            max_samples = [
                r for r in self.readings
                if ((now - r.stamp).total_seconds() < max_alarm_interval)
            ]
            max_threshold = int(self.max_alarm_threshold_input.get())
            if max_alarm_label == IMMEDIATE_KEY_WORD:
                trigger_max_alert = len(
                    [r for r in max_samples if r.value >= max_threshold]) > 0
            elif (len(max_samples) < len(self.readings)):
                trigger_max_alert = len(
                    [r for r in max_samples if r.value < max_threshold]) == 0

        trigger_min_alert = False
        if (self.min_alarm_enabled.get()):
            min_samples = [
                r for r in self.readings
                if ((now - r.stamp).total_seconds() < min_alarm_interval)
            ]
            min_threshold = int(self.min_alarm_threshold_input.get())
            if min_alarm_label == IMMEDIATE_KEY_WORD:
                trigger_min_alert = len(
                    [r for r in min_samples if r.value <= min_threshold]) > 0
            elif (len(min_samples) < len(self.readings)):
                trigger_min_alert = len(
                    [r for r in min_samples if r.value > min_threshold]) == 0

        if trigger_min_alert:
            self.add_alarm("Min Pressure Alarm")
        if trigger_max_alert:
            self.add_alarm("Max Pressure Alarm")

        if timestamp is not None:
            delta_seconds = (datetime.now() - timestamp).total_seconds()
            self.reading_timestamp.configure(
                text="Latest reading: {:10.2f} seconds ago".format(
                    delta_seconds))
            if (self.timeout_alarm_enabled.get()):
                timeout_threshold = TIMEOUT_OPTIONS_MAP[
                    self.timeout_alarm_interval_input.get()]
                if delta_seconds > timeout_threshold:
                    self.add_alarm("Signal Lost")

    @property
    def isOk(self):
        return self._isOk

    @isOk.setter
    def isOk(self, new_value):
        if self.debug: print('isOk being updated to ' + str(new_value))
        self._isOk = new_value
        if self.started_run and new_value == True:
            if self.debug: print('adding another run with ' + str(self.lookup))
            g_run(self, self.lookup, self.debug)
            #deprecated? keep it all on one thread for now
            #t = Thread(target = g_run, args =(self,self.lookup,self.debug ))

    #------------------------- aesthetics
    def place_dropdown(self, win, txt, vals, xstart=60, ystart=180):
        self.lab = Label(win, text=txt)
        self.lab.place(x=xstart, y=ystart)
        self.box = Combobox(win, values=vals)
        self.box.place(x=xstart + 160, y=ystart)

    def place_btn(self, win, txt, cmd, xstart=60, ystart=180):
        self.btn = Button(win, text=txt, command=cmd)
        self.btn.place(x=xstart, y=ystart)

    #-------------------------- ventilator methods
    def connect(self):
        if self.txtfld.get() == '':
            path = '/Users/juliagonski/Documents/Columbia/3DprinterAsVentilator/pronsoleWork/Printator/sim'
        else:
            path = self.txtfld.get()
        ser_printer = serial.Serial(path, baudRate)

        print("Connecting to printer...")
        time.sleep(1)  # Allow time for response
        if self.debug:
            print("Connection response from printer:",
                  ser_printer.read(ser_printer.inWaiting()))
        #ser_printer.write(str.encode('M400\n'))
        #ser_printer.write(str.encode('M400\n'))
        answer = ser_printer.readline()

        if 'ok' in answer.decode("utf-8", "ignore"):
            print("------ Done connecting!")
            print("")
        self.printer = ser_printer
        self.btn_init["state"] = "normal"

    def initialize(self):
        g_init(self, self.debug)
        self.btn_run["state"] = "normal"

    #def check_run(self, win):
    #  if self.started_run == 1:
    #    answer = self.waitForOk(self.printer)
    #    if self.debug: print("waiting response from printer?", answer)
    #    if 'ok' in answer.decode("utf-8", "ignore"): g_run(self,self.debug)
    #    #else: print('not ventilating, not adding more runs')
    #  win.after(2000,self.check_run,win)

    def start_run(self):
        self.printer.flush()
        self.started_run = True
        sel_tv = self.tv.get()
        sel_rr = self.rr.get()
        sel_ie = self.ie.get()
        self.lookup = sel_tv + "mL_" + sel_rr + "BPM_" + sel_ie
        print('Started new protocol: ' + str(self.lookup))
        self.btn_stop["state"] = "normal"
        #Start first thread, join subsequent ones
        t_orig = Thread(target=g_run, args=(self, self.lookup, self.debug))
        t_orig.start()

    def stop(self):
        self.started_run = False
        self.printer.flush()
        g_stop(self, self.debug)

    def waitForOk(self, ser_printer):
        if self.debug: print('BEGIN waitForOk')
        isItOk = False
        answer = ''
        quantity = ser_printer.inWaiting()
        while True:
            if quantity > 0:
                #answer += ser_printer.read(quantity)
                answer += ser_printer.read(quantity).decode("utf-8", "ignore")
                ##if 'ok' in answer.decode("utf-8", "ignore"):
                if 'ok' in answer:
                    if self.debug: print('found ok, breaking')
                    isItOk = True
                    break
            else:
                time.sleep(read_timeout)
            quantity = ser_printer.inWaiting()
            #if quantity == 0:
            #if self.debug: print('-------> No lines to read out')
            #print('ERROR connecting!!!')
            #raise ImportError()
            #break
        if self.debug: print('resulting answer: ', answer)
        return isItOk

    def waitForDONE(self, ser_printer):
        if self.debug: print('----- BEGIN waitForDONE')
        isItOk = False
        answer = ''
        quantity = ser_printer.inWaiting()
        while True:
            if quantity > 0:
                if self.debug:
                    print('----- reading what the printer has to say: ',
                          ser_printer.read(quantity).decode("utf-8", "ignore"))
                answer += ser_printer.read(quantity).decode("utf-8", "ignore")
                #deprecated new firmware 0622 if 'ok' in answer:
                if 'DECOMPRESSDONE' in answer:
                    if self.debug:
                        print('----- found DECMOMPRESSDONE in answer')
                    isItOk = True
                    break
            else:
                time.sleep(read_timeout)
            quantity = ser_printer.inWaiting()
            #if quantity == 0:
            #if self.debug: print('-------> No lines to read out')
            #print('ERROR connecting!!!')
            #raise ImportError()
            #break
        if self.debug:
            print(
                '----- resulting answer of concatented printer output (should end in DECOMPRESSDONE): ',
                answer)
        return isItOk
Exemplo n.º 16
0
class SoundPlayer(object):
    def __init__(self, soundDirPath):
        self.soundDirPath = soundDirPath
        self.loadSounds()
        self.musicPlayer = Player()
        self.queue = False
        self.queuePlayer = None
        self.enabled = True
        self.soundEffectVolume = 1.0  # between 0.0 and 1.0
        self._musicVolume = 1.0  # between 0.0 and 1.0

    """
        loads sounds from gui config file into dict.
        maps name to pyglet sound object.
        if ',stream' exists after filename in config file,
         will stream file instead of loading the whole thing in once.
    """

    def loadSounds(self):
        self.sounds = dict()
        soundTypes = dict(gui.config.items("sound_events"))
        for key in soundTypes:
            self._loadSoundResource(key)

    @staticmethod
    def _loadSoundEntry(key):
        entry = gui.config.get("sound_events", key)
        if "," in entry:
            sp = entry.split(",")
            fileName = sp[0]
            if sp[1] == "stream":
                stream = True
        else:
            fileName = entry
            stream = False
        return fileName, stream

    def _loadSoundResource(self, key):
        fileName, stream = self._loadSoundEntry(key)
        if key in self.sounds:
            self.sounds[key].delete()
        self.sounds[key] = pyglet.resource.media(self.soundDirPath + fileName, streaming=stream)

    def shutdown(self):
        from pyglet.media import avbin

        if self.musicPlayer.source is not None:
            avbin.av.avbin_close_file(self.musicPlayer.source._file)  # hack to ensure avbin closes properly.
        self.musicPlayer.delete()
        toDel = self.sounds.keys()
        for snd in toDel:
            del self.sounds[snd]

    @property
    def musicVolume(self):
        return self._soundEffectVolume

    @musicVolume.setter
    def musicVolume(self, value):
        self.musicPlayer.volume = value
        self._musicVolume = self.musicPlayer.volume

    def setMute(self, value):
        self.enabled = value

    def getSound(self, soundName):
        try:
            snd = self.sounds[soundName.lower()]
        except KeyError:
            print "Sound requsted to be played does not exist in config file."
            return None
        return snd

    def playMusic(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        if self.musicPlayer.playing and self.musicPlayer.source == snd:
            self.musicPlayer.seek(0)
            return
        else:
            # reload sound and reset Player obj
            # (streaming sounds needs to be reloaded every time)
            if isinstance(snd, pyglet.media.StreamingSource):
                self._loadSoundResource(soundName)
            self.musicPlayer.delete()
            self.musicPlayer = Player()
            self.musicPlayer.volume = self._musicVolume
        looper = pyglet.media.SourceGroup(snd.audio_format, None)
        looper.loop = True
        looper.queue(snd)
        self.musicPlayer.queue(looper)
        self.musicPlayer.play()

    def playEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        p = Player()
        p.volume = self.soundEffectVolume
        p.queue(snd)
        p.play()

    def startEffectsQueue(self):
        self.queue = True
        self.queuePlayer = Player()

    def queueEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        self.queuePlayer.queue(snd)

    """
        Plays the queue and resets queue state.
    """

    def playEffectsQueue(self):
        self.queuePlayer.volume = self.soundEffectVolume
        self.queuePlayer.play()
        self.queue = False
        self.queuePlayer = None
Exemplo n.º 17
0
class Video(object):
    """Read video file and draw it to the screen.

    Parameters
    ----------
    ec : instance of expyfun.ExperimentController
    file_name : str
        the video file path
    pos : array-like
        2-element array-like with X, Y elements.
    units : str
        Units to use for the position. See ``check_units`` for options.
    scale : float | str
        The scale factor. 1 is native size (pixel-to-pixel), 2 is twice as
        large, etc. If scale is a string, it must be either ``'fill'``
        (which ensures the entire ``ExperimentController`` window is
        covered by the video, at the expense of some parts of the video
        potentially being offscreen), or ``'fit'`` (which scales maximally
        while ensuring none of the video is offscreen, and may result in
        letterboxing or pillarboxing).
    center : bool
        If ``False``, the elements of ``pos`` specify the position of the lower
        left corner of the video frame; otherwise they position the center of
        the frame.
    visible : bool
        Whether to show the video when initialized. Can be toggled later using
        `Video.set_visible` method.

    Notes
    -----
    This is a somewhat pared-down implementation of video playback. Looping is
    not available, and the audio stream from the video file is discarded.
    Timing of individual frames is relegated to the pyglet media player's
    internal clock. Recommended for use only in paradigms where the relative
    timing of audio and video are unimportant (e.g., if the video is merely
    entertainment for the participant during a passive auditory task).
    """
    def __init__(self,
                 ec,
                 file_name,
                 pos=(0, 0),
                 units='norm',
                 scale=1.,
                 center=True,
                 visible=True):
        from pyglet.media import load, Player
        self._ec = ec
        # On Windows, the default is unaccelerated WMF, which is terribly slow.
        decoder = None
        if _new_pyglet():
            try:
                from pyglet.media.codecs.ffmpeg import FFmpegDecoder
                decoder = FFmpegDecoder()
            except Exception as exc:
                warnings.warn(
                    'FFmpeg decoder could not be instantiated, decoding '
                    f'performance could be compromised:\n{exc}')
        self._source = load(file_name, decoder=decoder)
        self._player = Player()
        with warnings.catch_warnings(record=True):  # deprecated eos_action
            self._player.queue(self._source)
        self._player._audio_player = None
        frame_rate = self.frame_rate
        if frame_rate is None:
            logger.warning('Frame rate could not be determined')
            frame_rate = 60.
        self._dt = 1. / frame_rate
        self._playing = False
        self._finished = False
        self._pos = pos
        self._units = units
        self._center = center
        self.set_scale(scale)  # also calls set_pos
        self._visible = visible
        self._eos_fun = self._eos_new if _new_pyglet() else self._eos_old

        self._program = _create_program(ec, tex_vert, tex_frag)
        gl.glUseProgram(self._program)
        self._buffers = dict()
        for key in ('position', 'texcoord'):
            self._buffers[key] = gl.GLuint(0)
            gl.glGenBuffers(1, pointer(self._buffers[key]))
        w, h = self.source_width, self.source_height
        tex = np.array([(0, h), (w, h), (w, 0), (0, 0)], np.float32)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._buffers['texcoord'])
        gl.glBufferData(gl.GL_ARRAY_BUFFER, tex.nbytes, tex.tobytes(),
                        gl.GL_DYNAMIC_DRAW)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
        gl.glUseProgram(0)

    def play(self, auto_draw=True):
        """Play video from current position.

        Parameters
        ----------
        auto_draw : bool
            If True, add ``self.draw`` to ``ec.on_every_flip``.

        Returns
        -------
        time : float
            The timestamp (on the parent ``ExperimentController`` timeline) at
            which ``play()`` was called.
        """
        if not self._playing:
            if auto_draw:
                self._ec.call_on_every_flip(self.draw)
            self._player.play()
            self._playing = True
        else:
            warnings.warn('ExperimentController.video.play() called when '
                          'already playing.')
        return self._ec.get_time()

    def pause(self):
        """Halt video playback.

        Returns
        -------
        time : float
            The timestamp (on the parent ``ExperimentController`` timeline) at
            which ``pause()`` was called.
        """
        if self._playing:
            try:
                idx = self._ec.on_every_flip_functions.index(self.draw)
            except ValueError:  # not auto_draw
                pass
            else:
                self._ec.on_every_flip_functions.pop(idx)
            self._player.pause()
            self._playing = False
        else:
            warnings.warn('ExperimentController.video.pause() called when '
                          'already paused.')
        return self._ec.get_time()

    def _delete(self):
        """Halt video playback and remove player."""
        if self._playing:
            self.pause()
        self._player.delete()

    def set_scale(self, scale=1.):
        """Set video scale.

        Parameters
        ----------
        scale : float | str
            The scale factor. 1 is native size (pixel-to-pixel), 2 is twice as
            large, etc. If scale is a string, it must be either ``'fill'``
            (which ensures the entire ``ExperimentController`` window is
            covered by the video, at the expense of some parts of the video
            potentially being offscreen), or ``'fit'`` (which scales maximally
            while ensuring none of the video is offscreen, which may result in
            letterboxing).
        """
        if isinstance(scale, string_types):
            _scale = self._ec.window_size_pix / np.array(
                (self.source_width, self.source_height), dtype=float)
            if scale == 'fit':
                scale = _scale.min()
            elif scale == 'fill':
                scale = _scale.max()
        self._scale = float(scale)  # allows [1, 1., '1']; others: ValueError
        if self._scale <= 0:
            raise ValueError('Video scale factor must be strictly positive.')
        self.set_pos(self._pos, self._units, self._center)

    def set_pos(self, pos, units='norm', center=True):
        """Set video position.

        Parameters
        ----------
        pos : array-like
            2-element array-like with X, Y elements.
        units : str
            Units to use for the position. See ``check_units`` for options.
        center : bool
            If ``False``, the elements of ``pos`` specify the position of the
            lower left corner of the video frame; otherwise they position the
            center of the frame.
        """
        pos = np.array(pos, float)
        if pos.size != 2:
            raise ValueError('pos must be a 2-element array')
        pos = np.reshape(pos, (2, 1))
        pix = self._ec._convert_units(pos, units, 'pix').ravel()
        offset = np.array((self.width, self.height)) // 2 if center else 0
        self._pos = pos
        self._actual_pos = pix - offset
        self._pos_unit = units
        self._pos_centered = center

    def _draw(self):
        tex = self._player.get_texture()
        gl.glUseProgram(self._program)
        gl.glActiveTexture(gl.GL_TEXTURE0)
        gl.glBindTexture(tex.target, tex.id)
        gl.glBindVertexArray(0)
        x, y = self._actual_pos
        w = self.source_width * self._scale
        h = self.source_height * self._scale
        pos = np.array([(x, y), (x + w, y), (x + w, y + h), (x, y + h)],
                       np.float32)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._buffers['position'])
        gl.glBufferData(gl.GL_ARRAY_BUFFER, pos.nbytes, pos.tobytes(),
                        gl.GL_DYNAMIC_DRAW)
        loc_pos = gl.glGetAttribLocation(self._program, b'a_position')
        gl.glEnableVertexAttribArray(loc_pos)
        gl.glVertexAttribPointer(loc_pos, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._buffers['texcoord'])
        loc_tex = gl.glGetAttribLocation(self._program, b'a_texcoord')
        gl.glEnableVertexAttribArray(loc_tex)
        gl.glVertexAttribPointer(loc_tex, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
        gl.glDrawArrays(gl.GL_QUADS, 0, 4)
        gl.glDisableVertexAttribArray(loc_pos)
        gl.glDisableVertexAttribArray(loc_tex)
        gl.glUseProgram(0)
        gl.glBindTexture(tex.target, 0)

    def draw(self):
        """Draw the video texture to the screen buffer."""
        self._player.update_texture()
        # detect end-of-stream to prevent pyglet from hanging:
        if not self._eos:
            if self._visible:
                self._draw()
        else:
            self._finished = True
            self.pause()
        self._ec.check_force_quit()

    def set_visible(self, show, flip=False):
        """Show/hide the video frame.

        Parameters
        ----------
        show : bool
            Show or hide.
        flip : bool
            If True, flip after showing or hiding.
        """
        if show:
            self._visible = True
            self._draw()
        else:
            self._visible = False
            self._ec.flip()
        if flip:
            self._ec.flip()

    # PROPERTIES
    @property
    def _eos(self):
        return self._eos_fun()

    def _eos_old(self):
        return (self._player._last_video_timestamp is not None
                and self._player._last_video_timestamp
                == self._source.get_next_video_timestamp())

    def _eos_new(self):
        ts = self._source.get_next_video_timestamp()
        dur = self._source._duration
        return ts is None or ts >= dur

    @property
    def playing(self):
        return self._playing

    @property
    def finished(self):
        return self._finished

    @property
    def position(self):
        return np.squeeze(self._pos)

    @property
    def scale(self):
        return self._scale

    @property
    def duration(self):
        return self._source.duration

    @property
    def frame_rate(self):
        return self._source.video_format.frame_rate

    @property
    def dt(self):
        return self._dt

    @property
    def time(self):
        return self._player.time

    @property
    def width(self):
        return self.source_width * self._scale

    @property
    def height(self):
        return self.source_height * self._scale

    @property
    def source_width(self):
        return self._source.video_format.width

    @property
    def source_height(self):
        return self._source.video_format.height

    @property
    def time_offset(self):
        return self._ec.get_time() - self._player.time
Exemplo n.º 18
0
class Video(object):
    """Read video file and draw it to the screen

    Parameters
    ----------
    ec : instance of expyfun.ExperimentController
    file_name : str
        the video file path
    pos : array-like
        2-element array-like with X, Y elements.
    units : str
        Units to use for the position. See ``check_units`` for options.
    scale : float | str
        The scale factor. 1 is native size (pixel-to-pixel), 2 is twice as
        large, etc. If `scale` is a string, it must be either ``'fill'``
        (which ensures the entire ``ExperimentController`` window is
        covered by the video, at the expense of some parts of the video
        potentially being offscreen), or ``'fit'`` (which scales maximally
        while ensuring none of the video is offscreen, and may result in
        letterboxing or pillarboxing).
    center : bool
        If ``False``, the elements of ``pos`` specify the position of the lower
        left corner of the video frame; otherwise they position the center of
        the frame.
    visible : bool
        Whether to show the video when initialized. Can be toggled later using
        ``set_visible`` method.

    Returns
    -------
    None

    Notes
    -----
    This is a somewhat pared-down implementation of video playback. Looping is
    not available, and the audio stream from the video file is discarded.
    Timing of individual frames is relegated to the pyglet media player's
    internal clock. Recommended for use only in paradigms where the relative
    timing of audio and video are unimportant (e.g., if the video is merely
    entertainment for the participant during a passive auditory task).
    """
    def __init__(self, ec, file_name, pos=(0, 0), units='norm', scale=1.,
                 center=True, visible=True):
        from pyglet.media import load, Player
        self._ec = ec
        self._source = load(file_name)
        self._player = Player()
        self._player.queue(self._source)
        self._player._audio_player = None
        frame_rate = self.frame_rate
        if frame_rate is None:
            logger.warning('Frame rate could not be determined')
            frame_rate = 60.
        self._dt = 1. / frame_rate
        self._texture = None
        self._playing = False
        self._finished = False
        self._pos = pos
        self._units = units
        self._center = center
        self.set_scale(scale)  # also calls set_pos
        self._visible = visible

    def play(self):
        """Play video from current position.

        Returns
        -------
        time : float
            The timestamp (on the parent ``ExperimentController`` timeline) at
            which ``play()`` was called.
        """
        if not self._playing:
            self._ec.call_on_every_flip(self.draw)
            self._player.play()
            self._playing = True
        else:
            warnings.warn('ExperimentController.video.play() called when '
                          'already playing.')
        return self._ec.get_time()

    def pause(self):
        """Halt video playback.

        Returns
        -------
        time : float
            The timestamp (on the parent ``ExperimentController`` timeline) at
            which ``pause()`` was called.
        """
        if self._playing:
            idx = self._ec.on_every_flip_functions.index(self.draw)
            self._ec.on_every_flip_functions.pop(idx)
            self._player.pause()
            self._playing = False
        else:
            warnings.warn('ExperimentController.video.pause() called when '
                          'already paused.')
        return self._ec.get_time()

    def _delete(self):
        """Halt video playback and remove player."""
        if self._playing:
            self.pause()
        self._player.delete()

    def _scale_texture(self):
        if self._texture:
            self._texture.width = self.source_width * self._scale
            self._texture.height = self.source_height * self._scale

    def set_scale(self, scale=1.):
        """Set video scale.

        Parameters
        ----------
        scale : float | str
            The scale factor. 1 is native size (pixel-to-pixel), 2 is twice as
            large, etc. If `scale` is a string, it must be either ``'fill'``
            (which ensures the entire ``ExperimentController`` window is
            covered by the video, at the expense of some parts of the video
            potentially being offscreen), or ``'fit'`` (which scales maximally
            while ensuring none of the video is offscreen, which may result in
            letterboxing).
        """
        if isinstance(scale, string_types):
            _scale = self._ec.window_size_pix / np.array((self.source_width,
                                                          self.source_height),
                                                         dtype=float)
            if scale == 'fit':
                scale = _scale.min()
            elif scale == 'fill':
                scale = _scale.max()
        self._scale = float(scale)  # allows [1, 1., '1']; others: ValueError
        if self._scale <= 0:
            raise ValueError('Video scale factor must be strictly positive.')
        self._scale_texture()
        self.set_pos(self._pos, self._units, self._center)

    def set_pos(self, pos, units='norm', center=True):
        """Set video position.

        Parameters
        ----------
        pos : array-like
            2-element array-like with X, Y elements.
        units : str
            Units to use for the position. See ``check_units`` for options.
        center : bool
            If ``False``, the elements of ``pos`` specify the position of the
            lower left corner of the video frame; otherwise they position the
            center of the frame.
        """
        pos = np.array(pos, float)
        if pos.size != 2:
            raise ValueError('pos must be a 2-element array')
        pos = np.reshape(pos, (2, 1))
        pix = self._ec._convert_units(pos, units, 'pix').ravel()
        offset = np.array((self.width, self.height)) // 2 if center else 0
        self._pos = pos
        self._actual_pos = pix - offset
        self._pos_unit = units
        self._pos_centered = center

    def _draw(self):
        self._texture = self._player.get_texture()
        self._scale_texture()
        self._texture.blit(*self._actual_pos)

    def draw(self):
        """Draw the video texture to the screen buffer."""
        self._player.update_texture()
        # detect end-of-stream to prevent pyglet from hanging:
        if not self._eos:
            if self._visible:
                self._draw()
        else:
            self._finished = True
            self.pause()
        self._ec.check_force_quit()

    def set_visible(self, show, flip=False):
        """Show/hide the video frame."""
        if show:
            self._visible = True
            self._draw()
        else:
            self._visible = False
            self._ec.flip()
        if flip:
            self._ec.flip()

    # PROPERTIES
    @property
    def _eos(self):
        return (self._player._last_video_timestamp is not None and
                self._player._last_video_timestamp ==
                self._source.get_next_video_timestamp())

    @property
    def playing(self):
        return self._playing

    @property
    def finished(self):
        return self._finished

    @property
    def position(self):
        return np.squeeze(self._pos)

    @property
    def scale(self):
        return self._scale

    @property
    def duration(self):
        return self._source.duration

    @property
    def frame_rate(self):
        return self._source.video_format.frame_rate

    @property
    def dt(self):
        return self._dt

    @property
    def time(self):
        return self._player.time

    @property
    def width(self):
        return self.source_width * self._scale

    @property
    def height(self):
        return self.source_height * self._scale

    @property
    def source_width(self):
        return self._source.video_format.width

    @property
    def source_height(self):
        return self._source.video_format.height

    @property
    def time_offset(self):
        return self._ec.get_time() - self._player.time
Exemplo n.º 19
0
from pyglet.media import Source, Player, load
a = {
    'id': 'Lost3',
    }
player = Player()
Source = load(a['id'] +'.mp3')
player.queue(Source)
player.play()
while True:
    playorpause = input('Press pl for play, pa for pause, st for stop')
    if playorpause == 'pl':
        player.play()
    elif playorpause == 'pa':
        player.pause()
    elif playorpause == 'st':
        player.pause()
        break
Exemplo n.º 20
0
 def queue(self, source):
     source_group = SourceGroup(source.audio_format, source.video_format)
     source_group.queue(source)
     Player.queue(self, source_group)
     source_group.loop = self.loop
Exemplo n.º 21
0
class Core(object):
    """central business logic of the game"""
    def __init__(self):
        """initializer"""
        self.game = None
        self.config = Config()
        self.sender = ""
        self.timestamp = 0
        self.TSP = 0
        # event handlers
        events.push_handlers(start_game=self.start_game,
                             sound_switch=self.sound_switch,
                             quick_battle=self.quick_battle,
                             modify_speed=self._change_time)
        self.intromusic = Player()
        source = load("music/music_title.wav")
        self.intromusic.queue(source)
        self.intromusic.volume=0.4 * self.config.sound_switch

    def tick_time(self, timestamp):
        self.timestamp=timestamp

    def _change_time(self, speed_modifier):
        """
        Changes time according to the request.
        """
        self.config.change_time_speed(speed_modifier)
        events.emit_speed_was_modified()

    def start_game(self,action):
        """event handler for starting the game"""
        self.game_name = "original64"  # "demo"  # TODO it should be gotten as an argument
        self.game = Game(self.game_name)
        XMLParser.load_cities(self.game_name)
        XMLParser.load_wagons(self.game_name)
        XMLParser.load_items(self.game_name)
        XMLParser.load_lang_file(self.game_name, "EN")
        self.query_mover("Transarctica").init_train()
        if action=="L":
            XMLParser.load_game(self.game_name, "Transarctica", self.query_mover("Transarctica"))  
            self.query_mover("Transarctica").game_loaded(self.config.loaded_objects["Transarctica"])
            for id in range(self.config.vutrain_count):
                self.query_mover("VUTrain"+str(id)).game_loaded(self.config.loaded_objects["VUTrain"+str(id)])
            for id in range(self.config.roamer_count):
                self.query_mover("Roamer"+str(id)).game_loaded(self.config.loaded_objects["Roamer"+str(id)])
        else:
            for id in range(self.config.vutrain_count):
                self.query_mover("VUTrain"+str(id)).respawn_timestamp+=self.config.start_timestamp

        self.query_mover("Transarctica").init_assets()
        events.emit_show_worldmap(self.game.map_file)

    def quick_battle(self):
        print("No boom today. Boom tomorrow. There's always a boom tomorrow.")
        events.emit_show_combat()

    def sound_switch(self):
        if self.config.sound_switch==1:
            self.config.sound_switch=0
        else:
            self.config.sound_switch=1
        self.intromusic.volume=0.4 * self.config.sound_switch


    def query_mover(self, actor_name):
        return self.game.query_mover(actor_name)

    def switch_intro_music(self, on_off):
        if on_off:
            self.intromusic.play()
        else:
            self.intromusic.pause()

    def save_game(self):
        XMLParser.save_game(self.game_name, "Transarctica", self.query_mover("Transarctica"))
Exemplo n.º 22
0
class Video(object):
    """Read video file and draw it to the screen

    Parameters
    ----------
    ec : instance of expyfun.ExperimentController
    file_name : str
        the video file path
    pos : array-like
        2-element array-like with X, Y elements.
    units : str
        Units to use for the position. See ``check_units`` for options.
    scale : float | str
        The scale factor. 1 is native size (pixel-to-pixel), 2 is twice as
        large, etc. If `scale` is a string, it must be either ``'fill'``
        (which ensures the entire ``ExperimentController`` window is
        covered by the video, at the expense of some parts of the video
        potentially being offscreen), or ``'fit'`` (which scales maximally
        while ensuring none of the video is offscreen, and may result in
        letterboxing or pillarboxing).
    center : bool
        If ``False``, the elements of ``pos`` specify the position of the lower
        left corner of the video frame; otherwise they position the center of
        the frame.
    visible : bool
        Whether to show the video when initialized. Can be toggled later using
        ``set_visible`` method.

    Returns
    -------
    None

    Notes
    -----
    This is a somewhat pared-down implementation of video playback. Looping is
    not available, and the audio stream from the video file is discarded.
    Timing of individual frames is relegated to the pyglet media player's
    internal clock. Recommended for use only in paradigms where the relative
    timing of audio and video are unimportant (e.g., if the video is merely
    entertainment for the participant during a passive auditory task).
    """
    def __init__(self,
                 ec,
                 file_name,
                 pos=(0, 0),
                 units='norm',
                 scale=1.,
                 center=True,
                 visible=True):
        from pyglet.media import load, Player
        self._ec = ec
        self._source = load(file_name)
        self._player = Player()
        with warnings.catch_warnings(record=True):  # deprecated eos_action
            self._player.queue(self._source)
        self._player._audio_player = None
        frame_rate = self.frame_rate
        if frame_rate is None:
            logger.warning('Frame rate could not be determined')
            frame_rate = 60.
        self._dt = 1. / frame_rate
        self._texture = None
        self._playing = False
        self._finished = False
        self._pos = pos
        self._units = units
        self._center = center
        self.set_scale(scale)  # also calls set_pos
        self._visible = visible

    def play(self):
        """Play video from current position.

        Returns
        -------
        time : float
            The timestamp (on the parent ``ExperimentController`` timeline) at
            which ``play()`` was called.
        """
        if not self._playing:
            self._ec.call_on_every_flip(self.draw)
            self._player.play()
            self._playing = True
        else:
            warnings.warn('ExperimentController.video.play() called when '
                          'already playing.')
        return self._ec.get_time()

    def pause(self):
        """Halt video playback.

        Returns
        -------
        time : float
            The timestamp (on the parent ``ExperimentController`` timeline) at
            which ``pause()`` was called.
        """
        if self._playing:
            idx = self._ec.on_every_flip_functions.index(self.draw)
            self._ec.on_every_flip_functions.pop(idx)
            self._player.pause()
            self._playing = False
        else:
            warnings.warn('ExperimentController.video.pause() called when '
                          'already paused.')
        return self._ec.get_time()

    def _delete(self):
        """Halt video playback and remove player."""
        if self._playing:
            self.pause()
        self._player.delete()

    def _scale_texture(self):
        if self._texture:
            self._texture.width = self.source_width * self._scale
            self._texture.height = self.source_height * self._scale

    def set_scale(self, scale=1.):
        """Set video scale.

        Parameters
        ----------
        scale : float | str
            The scale factor. 1 is native size (pixel-to-pixel), 2 is twice as
            large, etc. If `scale` is a string, it must be either ``'fill'``
            (which ensures the entire ``ExperimentController`` window is
            covered by the video, at the expense of some parts of the video
            potentially being offscreen), or ``'fit'`` (which scales maximally
            while ensuring none of the video is offscreen, which may result in
            letterboxing).
        """
        if isinstance(scale, string_types):
            _scale = self._ec.window_size_pix / np.array(
                (self.source_width, self.source_height), dtype=float)
            if scale == 'fit':
                scale = _scale.min()
            elif scale == 'fill':
                scale = _scale.max()
        self._scale = float(scale)  # allows [1, 1., '1']; others: ValueError
        if self._scale <= 0:
            raise ValueError('Video scale factor must be strictly positive.')
        self._scale_texture()
        self.set_pos(self._pos, self._units, self._center)

    def set_pos(self, pos, units='norm', center=True):
        """Set video position.

        Parameters
        ----------
        pos : array-like
            2-element array-like with X, Y elements.
        units : str
            Units to use for the position. See ``check_units`` for options.
        center : bool
            If ``False``, the elements of ``pos`` specify the position of the
            lower left corner of the video frame; otherwise they position the
            center of the frame.
        """
        pos = np.array(pos, float)
        if pos.size != 2:
            raise ValueError('pos must be a 2-element array')
        pos = np.reshape(pos, (2, 1))
        pix = self._ec._convert_units(pos, units, 'pix').ravel()
        offset = np.array((self.width, self.height)) // 2 if center else 0
        self._pos = pos
        self._actual_pos = pix - offset
        self._pos_unit = units
        self._pos_centered = center

    def _draw(self):
        self._texture = self._player.get_texture()
        self._scale_texture()
        self._texture.blit(*self._actual_pos)

    def draw(self):
        """Draw the video texture to the screen buffer."""
        self._player.update_texture()
        # detect end-of-stream to prevent pyglet from hanging:
        if not self._eos:
            if self._visible:
                self._draw()
        else:
            self._finished = True
            self.pause()
        self._ec.check_force_quit()

    def set_visible(self, show, flip=False):
        """Show/hide the video frame."""
        if show:
            self._visible = True
            self._draw()
        else:
            self._visible = False
            self._ec.flip()
        if flip:
            self._ec.flip()

    # PROPERTIES
    @property
    def _eos(self):
        return (self._player._last_video_timestamp is not None
                and self._player._last_video_timestamp
                == self._source.get_next_video_timestamp())

    @property
    def playing(self):
        return self._playing

    @property
    def finished(self):
        return self._finished

    @property
    def position(self):
        return np.squeeze(self._pos)

    @property
    def scale(self):
        return self._scale

    @property
    def duration(self):
        return self._source.duration

    @property
    def frame_rate(self):
        return self._source.video_format.frame_rate

    @property
    def dt(self):
        return self._dt

    @property
    def time(self):
        return self._player.time

    @property
    def width(self):
        return self.source_width * self._scale

    @property
    def height(self):
        return self.source_height * self._scale

    @property
    def source_width(self):
        return self._source.video_format.width

    @property
    def source_height(self):
        return self._source.video_format.height

    @property
    def time_offset(self):
        return self._ec.get_time() - self._player.time
Exemplo n.º 23
0
class AudioManager:
    def __init__(self, assets: Assets, channels: int):
        self.assets = assets
        self.channels = channels
        self.logger = logging.getLogger(__name__)

        self.music_player = Player()
        self.sfx_players = [Player() for player in range(self.channels)]

        self.music_player.volume = 0.5
        self.songs = {}

        self._debug_info()

        if get_audio_driver().__class__.__name__ == "DirectSoundDriver":
            self.logger.warn("Using the directsound driver may have negative impacts on performance. It is recomended to use OpenAL instead")

    def _play_song(self):
        if not self.music_player.playing:
            self.music_player.play()
        else:
            self.music_player.next_source()

    def _load_song(self, path: str) -> Source:
        if path not in self.songs:
            self.songs[path] = self.assets.get_pyglet_media(path)

        return self.songs[path]

    def _debug_info(self):
        self.logger.debug("=*=*=*=*=*= Audio Debug Information =*=*=*=*=*=")
        self.logger.debug(f"Audio Driver Class: { get_audio_driver().__class__.__name__ }")
        self.logger.debug(f"  FFmpeg Installed: { have_ffmpeg() }")
        self.logger.debug("=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=")

    def play_song(self, path: str, loop: bool = False):
        media_file = self._load_song(path)
        self.music_player.loop = loop
        self.music_player.queue(media_file)

        self._play_song()

    def load_songs(self, paths: list, loop: bool = False):
        for path in paths:
            media_file = self._load_song(path)
            self.music_player.queue(media_file)

        if loop:
            self.loop_songs_list = paths
            self.music_player.on_player_eos = lambda: self._loop_eos(paths)

    def _loop_eos(self, paths: list):
        self.load_songs(paths, True)
        self.play_songs()

    def play_songs(self):
        self._play_song()

    def get_music_volume(self) -> float:
        return self.music_player.volume

    def set_music_volume(self, volume: float):
        self.music_player.volume = volume

    def play_sfx(self, path: str):
        pass
Exemplo n.º 24
0
                      anchor_y = 'top')

state = 'playing'

pause_label = Label('PAUSED',
                    font_size=36,
                    x = window.width/2,
                    y = window.height/2,
                    anchor_x = 'center', anchor_y = 'center')

bounce_sound = resource.media('sounds/bounce.wav', streaming=False)
goal_sound = resource.media('sounds/goal.wav', streaming=False)

music = resource.media('sounds/ride-the-storm.ogg')
music_player = Player()
music_player.queue(music)
music_player.volume = 0.5
music_player.eos_action = music_player.EOS_LOOP
music_player.play()

@window.event
def on_draw():
    window.clear()
    if state == 'playing' or state == 'scored':
        ball.draw()
        paddle1.draw()
        paddle2.draw()
        score_label_1.draw()
        score_label_2.draw()
    if state == 'paused':
        pause_label.draw()
Exemplo n.º 25
0
class SoundManager(object):
    volume_factor = InterpDesc('_volume_factor')  # 音量系数

    def __init__(self):
        self.cur_bgm = None
        self.bgm_next = None
        self.bgm_switching = False
        self.bgm_player = Player()
        self.volume = 1.0  # 音量
        self.bgm_player.eos_action = Player.EOS_LOOP
        self.muted = False

    def switch_bgm(self, bgm):
        if self.muted:
            self.bgm_next = bgm
            return

        if not self.cur_bgm:
            self.instant_switch_bgm(bgm)
            return

        if bgm is self.cur_bgm:
            return

        self.volume_factor = LinearInterp(1.0, 0.0, 1.0)

        self.bgm_next = bgm
        if not self.bgm_switching:
            self.bgm_switching = True
            pyglet.clock.schedule_interval(self._set_vol, 0.1)
            pyglet.clock.schedule_once(self._bgm_fade_out_done, 1.0)

    def _bgm_fade_out_done(self, _=None):
        pyglet.clock.unschedule(self._set_vol)
        self.bgm_player.next()
        self.bgm_player.queue(self.bgm_next())
        self.volume_factor = 1.0
        self._set_vol()
        self.bgm_player.play()
        self.bgm_switching = False
        self.cur_bgm = self.bgm_next
        self.bgm_next = None

    def instant_switch_bgm(self, bgm):
        pyglet.clock.unschedule(self._bgm_fade_out_done)
        self.bgm_next = bgm
        if not self.muted:
            self._bgm_fade_out_done()

    def mute(self):
        if self.muted: return
        self.muted = True
        self.volume_factor = 0.0
        self.bgm_player.pause()
        pyglet.clock.unschedule(self._set_vol)
        pyglet.clock.unschedule(self._bgm_fade_out_done)
        self.bgm_next = self.cur_bgm
        self.cur_bgm = None

    def unmute(self):
        if not self.muted: return
        self.muted = False
        self.bgm_next and self.instant_switch_bgm(self.bgm_next)

    def play(self, snd):
        if self.muted: return
        player = ManagedSoundPlayer()
        player.volume = self.volume
        player.queue(snd)
        player.play()

    def set_volume(self, vol):
        self.volume = vol
        self._set_vol()

    def get_volume(self):
        return self.volume * self.volume_factor

    def _set_vol(self, _=None):
        self.bgm_player.volume = self.volume_factor * self.volume
Exemplo n.º 26
0
class SoundPlayer(object):
    def __init__(self, soundDirPath):
        self.soundDirPath = soundDirPath
        self.loadSounds()
        self.musicPlayer = Player()
        self.queue = False
        self.queuePlayer = None
        self.enabled = True
        self.soundEffectVolume = 1.0  # between 0.0 and 1.0
        self._musicVolume = 1.0  # between 0.0 and 1.0

    '''
        loads sounds from gui config file into dict.
        maps name to pyglet sound object.
        if ',stream' exists after filename in config file,
         will stream file instead of loading the whole thing in once.
    '''

    def loadSounds(self):
        self.sounds = dict()
        soundTypes = dict(gui.config.items('sound_events'))
        for key in soundTypes:
            self._loadSoundResource(key)

    @staticmethod
    def _loadSoundEntry(key):
        entry = gui.config.get('sound_events', key)
        if ',' in entry:
            sp = entry.split(",")
            fileName = sp[0]
            if sp[1] == "stream":
                stream = True
        else:
            fileName = entry
            stream = False
        return fileName, stream

    def _loadSoundResource(self, key):
        fileName, stream = self._loadSoundEntry(key)
        if key in self.sounds:
            self.sounds[key].delete()
        self.sounds[key] = pyglet.resource.media(self.soundDirPath + fileName,
                                                 streaming=stream)

    def shutdown(self):
        from pyglet.media import avbin
        if self.musicPlayer.source is not None:
            avbin.av.avbin_close_file(
                self.musicPlayer.source._file
            )  # hack to ensure avbin closes properly.
        self.musicPlayer.delete()
        toDel = self.sounds.keys()
        for snd in toDel:
            del self.sounds[snd]

    @property
    def musicVolume(self):
        return self._soundEffectVolume

    @musicVolume.setter
    def musicVolume(self, value):
        self.musicPlayer.volume = value
        self._musicVolume = self.musicPlayer.volume

    def setMute(self, value):
        self.enabled = value

    def getSound(self, soundName):
        try:
            snd = self.sounds[soundName.lower()]
        except KeyError:
            print "Sound requsted to be played does not exist in config file."
            return None
        return snd

    def playMusic(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        if self.musicPlayer.playing and self.musicPlayer.source == snd:
            self.musicPlayer.seek(0)
            return
        else:
            # reload sound and reset Player obj
            # (streaming sounds needs to be reloaded every time)
            if isinstance(snd, pyglet.media.StreamingSource):
                self._loadSoundResource(soundName)
            self.musicPlayer.delete()
            self.musicPlayer = Player()
            self.musicPlayer.volume = self._musicVolume
        looper = pyglet.media.SourceGroup(snd.audio_format, None)
        looper.loop = True
        looper.queue(snd)
        self.musicPlayer.queue(looper)
        self.musicPlayer.play()

    def playEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        p = Player()
        p.volume = self.soundEffectVolume
        p.queue(snd)
        p.play()

    def startEffectsQueue(self):
        self.queue = True
        self.queuePlayer = Player()

    def queueEffect(self, soundName):
        if not self.enabled:
            return
        soundName = soundName.lower()
        snd = self.getSound(soundName)
        assert snd
        self.queuePlayer.queue(snd)

    '''
        Plays the queue and resets queue state.
    '''

    def playEffectsQueue(self):
        self.queuePlayer.volume = self.soundEffectVolume
        self.queuePlayer.play()
        self.queue = False
        self.queuePlayer = None
Exemplo n.º 27
0
 def queue(self, source):
     source_group = SourceGroup(source.audio_format, source.video_format)
     source_group.queue(source)
     Player.queue(self, source_group)
     source_group.loop = self.loop
Exemplo n.º 28
0
class SoundManager(object):
    volume_factor = InterpDesc('_volume_factor')  # 音量系数

    def __init__(self):
        self.cur_bgm = None
        self.bgm_next = None
        self.bgm_switching = False
        self.bgm_player = Player()
        self.volume = 1.0  # 音量
        self.bgm_player.eos_action = Player.EOS_LOOP
        self.muted = False

    def switch_bgm(self, bgm):
        if self.muted:
            self.bgm_next = bgm
            return

        if not self.cur_bgm:
            self.instant_switch_bgm(bgm)
            return

        if bgm is self.cur_bgm:
            return

        self.volume_factor = LinearInterp(1.0, 0.0, 1.0)

        self.bgm_next = bgm
        if not self.bgm_switching:
            self.bgm_switching = True
            pyglet.clock.schedule_interval(self._set_vol, 0.1)
            pyglet.clock.schedule_once(self._bgm_fade_out_done, 1.0)

    def _bgm_fade_out_done(self, _=None):
        pyglet.clock.unschedule(self._set_vol)
        self.bgm_player.next()
        self.bgm_player.queue(self.bgm_next())
        self.volume_factor = 1.0
        self._set_vol()
        self.bgm_player.play()
        self.bgm_switching = False
        self.cur_bgm = self.bgm_next
        self.bgm_next = None

    def instant_switch_bgm(self, bgm):
        pyglet.clock.unschedule(self._bgm_fade_out_done)
        self.bgm_next = bgm
        if not self.muted:
            self._bgm_fade_out_done()

    def mute(self):
        if self.muted: return
        self.muted = True
        self.volume_factor = 0.0
        self.bgm_player.pause()
        pyglet.clock.unschedule(self._set_vol)
        pyglet.clock.unschedule(self._bgm_fade_out_done)
        self.bgm_next = self.cur_bgm
        self.cur_bgm = None

    def unmute(self):
        if not self.muted: return
        self.muted = False
        self.bgm_next and self.instant_switch_bgm(self.bgm_next)

    def play(self, snd):
        if self.muted: return
        player = ManagedSoundPlayer()
        player.volume = self.volume
        player.queue(snd)
        player.play()

    def set_volume(self, vol):
        self.volume = vol
        self._set_vol()

    def _set_vol(self, _=None):
        self.bgm_player.volume = self.volume_factor * self.volume
Exemplo n.º 29
0
    'progress_hooks': [my_hook],
}

with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=BaW_jenozKc'])

with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    info_dict = ydl.extract_info("https://www.youtube.com/watch?v=CxMvQkcdPl8",
                                 download=True)

with open('data.json', 'w') as f:
    json.dump(info_dict, f)

# newString = 'I love coding more than anything else'
# with open("testFile.txt", 'a') as out:
#     out.write(newString )

# music = pyglet.resource.media('crowd-cheering.wav.mp3')
# music.play()
# pyglet.app.run()

from pyglet.media import Source, Player, load

player = Player()
source = load('crowd-cheering.wav.mp3')
player.queue(source)
player.play()
while True:
    input('Press any key to exit')
    break
Exemplo n.º 30
0
class BeatSaber(moderngl_window.WindowConfig):
    title = "Beat Saber Light Show"
    window_size = 1920, 1080
    cursor = False
    aspect_ratio = None

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.wnd.mouse_exclusivity = False
        self.bpm = 242  # Hardcode bpm from info.dat
        self.camera = KeyboardCamera(self.wnd.keys,
                                     fov=60,
                                     near=1.0,
                                     far=1000.0)
        self.camera.velocity = 50
        self.camera_enabled = False

        meta = self.load_json('megalovania_remix/info.dat')
        self.map = BSScene(
            self.load_scene('bs_map3.glb'),
            self.camera,
            BSTrack('megalovania_remix/Expert.dat', meta['_beatsPerMinute']),
        )

        self.quad_fs = geometry.quad_fs()

        # Postprocess programs
        self.copy_prog = self.load_program('programs/copy.glsl')
        self.copy_greyscale_prog = self.load_program(
            'programs/copy_greyscale.glsl')
        self.blur_h_prog = self.load_program('programs/blur_h.glsl')
        self.blur_v_prog = self.load_program('programs/blur_v.glsl')
        self.combine = self.load_program('programs/combine.glsl')
        self.combine['texture1'] = 1

        # blur stuff
        self.offscreen_texture = self.ctx.texture(
            (self.wnd.buffer_width, self.wnd.buffer_height), 4)
        self.offscreen_depth = self.ctx.depth_texture(
            (self.wnd.buffer_width, self.wnd.buffer_height))
        self.offscreen = self.ctx.framebuffer(
            color_attachments=[self.offscreen_texture],
            depth_attachment=self.offscreen_depth,
        )
        bd = 1
        self.blur_h_texture = self.ctx.texture(
            (self.wnd.buffer_width // bd, self.wnd.buffer_height // bd), 4)
        self.blur_h_texture.repeat_x = False
        self.blur_h_texture.repeat_y = False
        self.blur_h = self.ctx.framebuffer(
            color_attachments=[self.blur_h_texture])
        self.blur_v_texture = self.ctx.texture(
            (self.wnd.buffer_width // bd, self.wnd.buffer_height // bd), 4)
        self.blur_v_texture.repeat_x = False
        self.blur_v_texture.repeat_y = False
        self.blur_v = self.ctx.framebuffer(
            color_attachments=[self.blur_v_texture])

        self.music_player = Player()
        self.music_source = StaticSource(
            load(RESOURCE_DIR / 'megalovania_remix/song.wav'))
        self.music_player.queue(self.music_source)
        self.music_player.play()
        # self.music_player.seek(60.0 * 4 + 50)
        self.music_player.volume = 1.0

    def render(self, time, frame_time):
        self.offscreen.clear()
        self.blur_h.clear()
        self.blur_v.clear()
        time = self.music_player.time

        self.offscreen.use()
        self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE)
        self.map.render(self.camera, time, frame_time)

        self.ctx.enable_only(moderngl.NOTHING)

        self.blur_v.use()
        self.offscreen_texture.use(location=0)
        self.quad_fs.render(self.copy_prog)
        self.blur_v_texture.build_mipmaps(max_level=10)

        self.blur_h.use()
        self.blur_v_texture.use(location=0)
        self.quad_fs.render(self.blur_h_prog)
        self.blur_h_texture.build_mipmaps(max_level=10)

        self.blur_v.use()
        self.blur_h_texture.use(location=0)
        self.quad_fs.render(self.blur_v_prog)

        # Back to screen
        self.wnd.fbo.use()
        self.offscreen_texture.use(location=0)
        self.blur_v_texture.use(location=1)
        self.quad_fs.render(self.combine)

    def key_event(self, key, action, modifiers):
        keys = self.wnd.keys

        if self.camera_enabled:
            self.camera.key_input(key, action, modifiers)

        if action == keys.ACTION_PRESS:
            if key == keys.C:
                self.camera_enabled = not self.camera_enabled
                self.wnd.mouse_exclusivity = self.camera_enabled
                self.wnd.cursor = not self.camera_enabled
            if key == keys.SPACE:
                self.timer.toggle_pause()
                if self.music_player.playing:
                    self.music_player.pause()
                else:
                    self.music_player.play()

    def mouse_position_event(self, x: int, y: int, dx, dy):
        if self.camera_enabled:
            self.camera.rot_state(-dx, -dy)

    def resize(self, width: int, height: int):
        self.camera.projection.update(aspect_ratio=self.wnd.aspect_ratio)
        self.map.resize()