Reputation: 23
So I wanted to build a metronome and decided to use pyaudio. I know there are other ways but I want to make something else later with that.
Thats my Code so far:
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
def play_audio(filename):
wf=wave.open(filename,"rb")
p=pyaudio.PyAudio()
stream_play=p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while True:
if data != '':
stream_play.write(data)
data = wf.readframes(CHUNK)
if data == b"":
break
stream_play.stop_stream()
stream_play.close()
p.terminate()
def metronom(bpm):
while True:
play_callback(beep)
time.sleep(60/bpm)
beep="beep-07a.wav"
I thought it worked out, but unfortunately the timing is completely off. I also tried it with a callback function, but had the same wrong timing.
THE SOLUTION NOW LOOKS LIKE THIS
def metronom(bpm):
while True:
startTime = time.time()
play_callback(beep)
endTime=time.time()-startTime
time.sleep(60/bpm-endTime)
Upvotes: 1
Views: 327
Reputation: 138
You want the play_audio function to be called every 60/bpm seconds, but the function call itself takes time: you need to read the file, open the stream, play the file (who knows how long it is) and close the stream. So that adds to the time from one click to the next.
To fix this problem, you could try subtracting the time it takes to run the play_audio function from the time you sleep. You could also experiment with running play_audio on a separate thread.
Upvotes: 1
Reputation: 102
If you metronome just need a tick sound and if you are on windows OS you can easily use Winsound to create a metronome, try following.
import winsound
frequency = 25 # Set Frequency To 25 Hertz
duration = 5*1000 # Set Duration To 5000 ms or 5 second
winsound.Beep(frequency, duration)
Upvotes: 0