Reputation: 33499
I am trying to use PyAudio (installed via "sudo apt-get install python-pyaudio") to play a recorded sample multiple times.
I've tried:
num_repeats = 6
out.write(numpy.hstack(numpy.tile(d, num_repeats)))
but this plays the audio sample only 3 times. As far as I can hear, it always plays exactly half the data I give it. (e.g if I simply use out.write(d) I only hear half the recorded sample)
There is an obvious work around (num_repeats *= 2) but I would like to understand why this is necessary!
import pyaudio
import numpy
p = pyaudio.PyAudio()
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 80000
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)
frame = stream.read(CHUNK)
stream.stop_stream()
stream.close()
d = numpy.fromstring(frame, 'int16')
out = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True)
num_repeats = 6
out.write(numpy.hstack(numpy.tile(d, num_repeats)))
out.close()
p.terminate()
It behaves the same (i.e. only 3 repeats) whether I use 2 channels or 1.
Upvotes: 2
Views: 886
Reputation: 166
In my case I solved the same issue adding pause before closing the stream. Not sure if it is expected behaviour, but audio on my embedded device was played in async way after writing to the stream. So I had to wait before closing the stream. The setup I finished with was like this:
import time
...
#calculate clip duration in seconds
duration = float(clip_data_length) / rate / bytes_per_sample / channels
startTime = time.time()
stream.write(wav_data)
endTime = time.time()
if ((endTime - startTime) < duration):
time.sleep(duration - (endTime - startTime))
time.sleep(0.1)
stream.close()
Upvotes: 0
Reputation: 1473
Convert the numpy array to a binary before handing it over. You can use .tobinary() or .tostring()
In case you have matched the datatype this should work.
Upvotes: 2