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()
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)
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()
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 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 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 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()
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)
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()
class ATrackFactory: def __init__(self): self.loaded = False self.playing = False self.playlist = [] self.index = 0 self.player = Player() def load(self): pass def play(self): if not self.loaded: self.load() self.playing = True while self.playing: track = self.playlist[self.index] # Pass the own player track.play(self.player) self.index += 1 if self.index >= len(self.playlist): self.index = 0 def pause(self): if self.player.playing: self.player.pause() else: self.player.play() def next(self): if self.playing: self.playing = False self.index += 1 self.play() def previous(self): if self.playing: self.playing = False self.index -= 1 self.play()
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()
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"))
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
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
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
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
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
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
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
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
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() @window.event def on_key_press(symbol, modifiers):
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
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
'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
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()