Peter de Rivaz
Peter de Rivaz

Reputation: 33499

Why does PyAudio only play half my audio?

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!

Full code to reproduce problem

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

Answers (2)

GiedriusL
GiedriusL

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

0-_-0
0-_-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

Related Questions