play as many sounds as loop count in python - python

I want the alarm.play() function to repeat for the number of loops and ring 10 times as in the example, but it just keeps ringing once every time I try or change it. How can I fix this? And does it make more sense to use for instead of while ?
import time
import vlc
alarm = vlc.MediaPlayer("path")
m=0
while m<=10:
alarm.play()
time.sleep(1)
m +=1

just stop the alarm at the end of loop and befor stop it create loop for stop executing while the sound is playing
import time
import vlc
alarm = vlc.MediaPlayer("path")
m = 0
while m <= 10:
alarm.play()
time.sleep(1)
m += 1
while alarm.is_playing():
pass
alarm.stop()

Related

jack audio - sync application to master

I'm wondering about the correct way of keeping my application in sync with a timebase master application using the jack audio api.
Let's say I have Hydrogen drum machine running in master mode and I want to print a message on every 1/4 note Hydrogen is playing.
This is what I would do intuitive (using python):
#!/usr/bin/env python3
import time
import jack
client = jack.Client('klicker')
def print_msg (last_tick):
state, pos = client.transport_query()
if state == jack.ROLLING:
if pos['tick'] < last_tick:
print ("klick")
return pos['tick']
with client:
last_tick = 0
while True:
last_tick = print_msg (last_tick)
time.sleep(0.00002)
So I'm running a loop with very little sleep time and check in every iteration if the current beat is already over.
This seems a little bit dirty and imprecise to me. So what would the right way of solving this problem?
Finally, I found a solution which semms to be more precise:
First, we want to use the process callback instead of an infinite loop.
def process (f):
Every time this callback is called, f number of frames are processed. The sample rate tells us how many frames we will process in 1 second. By multiplying this with 60 and dividing by the number of beats per minute we get the number of frames which are processed in one beat.
#!/usr/bin/env python3
import jack
client = jack.Client('Klick')
frame_counter = 0
#client.set_process_callback
def process (f):
global frame_counter
state, pos = client.transport_query()
if state == jack.ROLLING:
frame_counter += f
# how many frames are get processed in 1 beat?
frames_per_beat = client.samplerate * 60 / pos['beats_per_minute']
# did we process enough frames for 1 beat?
if frame_counter >= frames_per_beat:
print ('klick')
frame_counter -= frames_per_beat
with client:
client.activate()
input()

How to keep track of time in python without sleeping?

I'm wondering how I can play a .wav file after some time has passed without using the sleep function. Essentially, I was wondering if there is a way to keep track of time in Python, so that, after say 15 seconds has elapsed, I can play a sound without pausing my code.
# checks if I should play the sound or not and, sets the variable
def Tyler(self):
if self.started == 1:
if self.isTaiwan == 0:
if self.myListNames[self.current_player_id / 3].lower() == "tyler":
self.isTyler = 1
else:
self.isTyler = 0
self.Tyler()
if self.isTyler == 1:
time.sleep(6)
winsound.PlaySound("tyler.wav", winsound.SND_ASYNC)
# This is where I would want to check to see
# if some time has passed and the conditions haven't changed.
from time import time
def delay(secs):
init_time = time()
while time() < init_time+secs: pass
This won't use sleep but it is similar. Still uses time module

How many Windows wall clock seconds are there in an actual second?

This code:
import random,time
raw_input()
while True:
try:
TIME += 0
except:
TIME = time.clock()
x = random.random()
if x > 0.999999:
print x
print time.clock()-TIME
break
Provided this output:
0.999999910337
63.5525445557
However, I tested on a stopwatch and I seemed to get a second and 3 quarters on the stopwatch. I wasn't going for an accurate reading, I was simply trying to figure out how many Windows wall clock seconds there are to every second.
2nd Try
0.999999028728
0.93168230208
Took a second and a quarter
I kept getting weird answers. Anyway, does anybody know? Or is it a rate?

What's the proper way to write a game loop in Python?

I'm trying to write a python game loop that hopefully takes into account FPS. What is the correct way to call the loop? Some of the possibilities I've considered are below. I'm trying not to use a library like pygame.
1.
while True:
mainLoop()
2.
def mainLoop():
# run some game code
time.sleep(Interval)
mainLoop()
3.
def mainLoop():
# run some game code
threading.timer(Interval, mainLoop).start()
4.
Use sched.scheduler?
If I understood correctly you want to base your game logic on a time delta.
Try getting a time delta between every frame and then have your objects move with respect to that time delta.
import time
while True:
# dt is the time delta in seconds (float).
currentTime = time.time()
dt = currentTime - lastFrameTime
lastFrameTime = currentTime
game_logic(dt)
def game_logic(dt):
# Where speed might be a vector. E.g speed.x = 1 means
# you will move by 1 unit per second on x's direction.
plane.position += speed * dt;
If you also want to limit your frames per second, an easy way would be sleeping the appropriate amount of time after every update.
FPS = 60
while True:
sleepTime = 1./FPS - (currentTime - lastFrameTime)
if sleepTime > 0:
time.sleep(sleepTime)
Be aware thought that this will only work if your hardware is more than fast enough for your game. For more information about game loops check this.
PS) Sorry for the Javaish variable names... Just took a break from some Java coding.

How do I ensure that a Python while-loop takes a particular amount of time to run?

I'm reading serial data with a while loop. However, I have no control over the sample rate.
The code itself seems to take 0.2s to run, so I know I won't be able to go any faster than that. But I would like to be able to control precisely how much slower I sample.
I feel like I could do it using 'sleep', but the problem is that there is potential that at different points the loop itself will take longer to read(depending on precisely what is being transmitted over serial data), so the code would have to make up the balance.
For example, let's say I want to sample every 1s, and the loop takes anywhere from 0.2s to 0.3s to run. My code needs to be smart enough to sleep for 0.8s (if the loop takes 0.2s) or 0.7s (if the loop takes 0.3s).
import serial
import csv
import time
#open serial stream
while True:
#read and print a line
sample_value=ser.readline()
sample_time=time.time()-zero
sample_line=str(sample_time)+','+str(sample_value)
outfile.write(sample_line)
print 'time: ',sample_time,', value: ',sample_value
Just measure the time running your code takes every iteration of the loop, and sleep accordingly:
import time
while True:
now = time.time() # get the time
do_something() # do your stuff
elapsed = time.time() - now # how long was it running?
time.sleep(1.-elapsed) # sleep accordingly so the full iteration takes 1 second
Of course not 100% perfect (maybe off one millisecond or another from time to time), but I guess it's good enough.
Another nice approach is using twisted's LoopingCall:
from twisted.internet import task
from twisted.internet import reactor
def do_something():
pass # do your work here
task.LoopingCall(do_something).start(1.0)
reactor.run()
An rather elegant method is you're working on UNIX : use the signal library
The code :
import signal
def _handle_timeout():
print "timeout hit" # Do nothing here
def second(count):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(1)
try:
count += 1 # put your function here
signal.pause()
finally:
signal.alarm(0)
return count
if __name__ == '__main__':
count = 0
count = second(count)
count = second(count)
count = second(count)
count = second(count)
count = second(count)
print count
And the timing :
georgesl#cleese:~/Bureau$ time python timer.py
5
real 0m5.081s
user 0m0.068s
sys 0m0.004s
Two caveats though : it only works on *nix, and it is not multithread-safe.
At the beginning of the loop check if the appropriate amount of time has passed. If it has not, sleep.
# Set up initial conditions for sample_time outside the loop
sample_period = ???
next_min_time = 0
while True:
sample_time = time.time() - zero
if sample_time < next_min_time:
time.sleep(next_min_time - sample_time)
continue
# read and print a line
sample_value = ser.readline()
sample_line = str(sample_time)+','+str(sample_value)
outfile.write(sample_line)
print 'time: {}, value: {}'.format(sample_time, sample_value)
next_min_time = sample_time + sample_period

Categories

Resources