Closed josephernest closed 8 years ago
I have the same problem with streaming live radio input through my USB sound card on Pi2, until I realised that having 2 channels (stereo) stream made my Pi2 processor suffered a lot... stuttering for a few seconds before the stream died completely. I tried changing channels = 1, it runs with no problem for half hour. However, listening a mono sound is not as nice. I hope there's an improvement with the PyAudio library for Python 3 to somehow compress the throughput.
I think the problem doesn't come from PyAudio / Python. It is only a wrapper for PortAudio, that works on thousands of audio devices. As previously said, PyAudio works perfectly on RaspberryPi when we use a USB DAC as audio device.
The problem seems really to come from RaspberryPi's built-in audio snd_bcm2835
.
What do you think @LinuxCircle ?
I can confirm I see the issue with pyaudio + snd_bcm2835. Not sure where the issue lies currently.
I've done some logging on firmware side. 44.1kHz audio with 2channels of 16-bits produces 176.4K/s. We get audio in 8K chunks. That should be 21.5 chunks/s.
For the first 10 seconds we get 21 or 22 chunks each second. Then it drops down to about 16 chunks per second so we start underrunning.
So I think firmware is behaving okay. Possibly alsa driver or portaudio is misbehaving.
It looks like portaudio has some latency options. I wonder if these can be set through PyAudio? http://portaudio.com/docs/v19-doxydocs/structPaDeviceInfo.html
Is there alternative to pyaudio? All I want is to capture and playback the voice, and then translate speech into text.
On Fri, Sep 4, 2015 at 2:39 AM, popcornmix notifications@github.com wrote:
I've done some logging on firmware side. 44.1kHz audio with 2channels of 16-bits produces 176.4K/s. We get audio in 8K chunks. That should be 21.5 chunks/s.
For the first 10 seconds we get 21 or 22 chunks each second. Then it drops down to about 16 chunks per second so we start underrunning.
So I think firmware is behaving okay. Possibly alsa driver or portaudio is misbehaving.
It looks like portaudio has some latency options. I wonder if these can be set through PyAudio? http://portaudio.com/docs/v19-doxydocs/structPaDeviceInfo.html
— Reply to this email directly or view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-137506310.
Thanks @popcornmix for your tests ! I did some tests with various latency, the problem is always the same.
It's annoying because PyAudio is one of the most used Python module that provides writing audio with a callback...
Are you sure it's because of PyAudio and not a problem with snd_bcm2835
?
What improvements could be possible on this audio driver to help better performance?
I find the fact that PyAudio + RaspberryPi doesn't work out of the box is a major problem for the development of audio projects.
For my open-source project www.samplerbox.org, we have to ask people to buy a DAC instead, which is annoying...
Hi, I had the same problem, and I fix it by
pcm.convert {
type plug;
slave {
pcm default;
rate 48000;
}
}
Bonjour @yienyien , Can you elaborate a bit more? How did you solve the problem? What do you exactly do in 1. ? What's 3., where do you put this code?
If you could paste a reproducible code somewhere on Github, it would help a lot a lot a lot :)
Thanks in advance @yienyien
Sorry to ask again @yienyien but if you had details about your solution , it would be wonderful for many audio projects, stuck with PyAudio + RaspPi 's built-in soundcard...
Ok sorry, I will try to clarify.
~/.asoundrc
(see http://www.alsa-project.org/main/index.php/Asoundrc for more details)pcm.convert {
type plug;
slave {
pcm default;
rate 48000;
}
}
It will create a new "pcm" device that resamples automagically the input framerate to 48Khz that seems to be the "good" framerate for snd_bcm2835
import pyaudio
import wave
import sys
import time
def play(device_name, path):
f = wave.open(path, "rb")
# Create a pyaudio object
audio = pyaudio.PyAudio()
# Looking for the right device by name
for index in range(audio.get_device_count()):
desc = audio.get_device_info_by_index(index)
if desc["name"] == device_name:
device = index
rate = int(desc["defaultSampleRate"])
break
# Define a reader callback
def callback(in_data, frame_count, time_info, status):
data = f.readframes(frame_count)
return (data, pyaudio.paContinue)
# Create the stream with right device, get framerate, the
# number of channel and the format from the wave file
stream = audio.open(format = audio.get_format_from_width(f.getsampwidth()),
channels = f.getnchannels(),
rate = f.getframerate(),
output_device_index = device,
output = True,
stream_callback = callback)
# Wait the stream end
while stream.is_active():
time.sleep(0.1)
# Close all
stream.stop_stream()
stream.close()
audio.terminate()
if __name__ == "__main__":
play("convert", sys.argv[1])
Keep me informed
@josephernest is it working now ?
Hi @yienyien . I have added these lines into /etc/asound.conf
.
Unfortunately, not working (yet)... When listing the audio devices with:
import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
dev = p.get_device_info_by_index(i)
print dev
I get this new error:
Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams,
&alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 924
Any idea?
PS : these two things might be interesting:
root@samplerbox:~# aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
convert
default:CARD=ALSA
bcm2835 ALSA, bcm2835 ALSA
Default Audio Device
sysdefault:CARD=ALSA
bcm2835 ALSA, bcm2835 ALSA
Default Audio Device
dmix:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample mixing device
dmix:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample mixing device
dsnoop:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample snooping device
dsnoop:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample snooping device
hw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct hardware device without any conversions
hw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct hardware device without any conversions
plughw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Hardware device with all software conversions
plughw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Hardware device with all software conversions
default:CARD=DAC
USB Audio DAC, USB Audio
Default Audio Device
sysdefault:CARD=DAC
USB Audio DAC, USB Audio
Default Audio Device
front:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
Front speakers
surround21:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
4.0 Surround output to Front and Rear speakers
surround41:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
IEC958 (S/PDIF) Digital Audio Output
dmix:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
Direct sample mixing device
dsnoop:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
Direct sample snooping device
hw:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
Direct hardware device without any conversions
plughw:CARD=DAC,DEV=0
USB Audio DAC, USB Audio
Hardware device with all software conversions
and the result of the previous Python code (list all devices) :
Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 924
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.005804988662131519, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 0, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'bcm2835 ALSA: - (hw:0,0)', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.005804988662131519, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 1, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'bcm2835 ALSA: IEC958/HDMI (hw:0,1)', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008684807256235827, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 2, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'USB Audio DAC: - (hw:1,0)', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.005804988662131519, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 3, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 128L, 'name': u'sysdefault', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.005804988662131519, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 4, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 128L, 'name': u'default', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 48000.0, 'defaultLowOutputLatency': 0.021333333333333333, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 5, 'defaultHighOutputLatency': 0.021333333333333333, 'maxOutputChannels': 2L, 'name': u'dmix', 'defaultHighInputLatency': -1.0}
(suite)
I also tried with
pcm.blah {
type rate
slave {
pcm "hw:0,0"
rate 48000
}
}
Nearly the same error when listing all the available devices with PyAudio:
Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 934
Have you tried on a RPi, does it work for you @yienyien ? Which distribution?
I have a raspbian:
> uname -a
Linux raspberrypi 4.1.6-v7+ #810 SMP PREEMPT Tue Aug 18 15:32:12 BST 2015 armv7l GNU/Linux
I have installed PyAudio in a virtualenv with pip, then I have the 0.2.8 in my project (against 0.2.4 by default in raspbian) because the my 0.2.4 does not support the callback style.
> pip freeze
PIL==1.1.7
PyAudio==0.2.8
RPi.GPIO==0.5.11
angus-sdk-python==0.0.7
argparse==1.2.1
backports.ssl-match-hostname==3.4.0.2
certifi==2015.09.06.2
distribute==0.6.24
futures==3.0.3
mcpi==0.1.1
medusa==0.5.4
meld3==0.6.5
numpy==1.6.2
pexpect==2.4
picamera==1.10
pifacecommon==4.1.2
pifacedigitalio==3.0.4
py==1.4.30
pygame==1.9.1release
pygobject==3.8.2
pyserial==2.5
pytest==2.6.4
reportlab==2.5
requests==2.5.3
requests-futures==0.9.5
six==1.9.0
supervisor==3.0a8
tornado==4.2.1
virtualenv==1.7.1.2
wsgiref==0.1.2
But that do not explain your error because with the default PyAudio (from distrib) your script output is:
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.011609977324263039, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0, 'structVersion': 2, 'hostApi': 0, 'index': 0, 'defaultHighOutputLatency': 0.046439909297052155, 'maxOutputChannels': 2, 'name': 'bcm2835 ALSA: bcm2835 ALSA (hw:0,0)', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.011609977324263039, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0, 'structVersion': 2, 'hostApi': 0, 'index': 1, 'defaultHighOutputLatency': 0.046439909297052155, 'maxOutputChannels': 2, 'name': 'bcm2835 ALSA: bcm2835 IEC958/HDMI (hw:0,1)', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.011609977324263039, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0, 'structVersion': 2, 'hostApi': 0, 'index': 2, 'defaultHighOutputLatency': 0.046439909297052155, 'maxOutputChannels': 128, 'name': 'sysdefault', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.011609977324263039, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0, 'structVersion': 2, 'hostApi': 0, 'index': 3, 'defaultHighOutputLatency': 0.046439909297052155, 'maxOutputChannels': 128, 'name': 'convert', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.011609977324263039, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0, 'structVersion': 2, 'hostApi': 0, 'index': 4, 'defaultHighOutputLatency': 0.046439909297052155, 'maxOutputChannels': 128, 'name': 'default', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 48000.0, 'defaultLowOutputLatency': 0.042666666666666665, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0, 'structVersion': 2, 'hostApi': 0, 'index': 5, 'defaultHighOutputLatency': 0.042666666666666665, 'maxOutputChannels': 2, 'name': 'dmix', 'defaultHighInputLatency': -1.0}
The error seems to be come from "portaudio" my version is:
dpkg -l | grep portaudio
ii libportaudio2:armhf 19+svn20111121-1 armhf Portable audio I/O - shared library
ii libportaudiocpp0:armhf 19+svn20111121-1 armhf Portable audio I/O C++ bindings - shared library
ii portaudio19-dev 19+svn20111121-1 armhf Portable audio I/O - development files
> cat /etc/apt/sources.list
deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspbian.org/raspbian/ wheezy main contrib non-free rpi
Hi @yienyien . I tried a lots of time, but unfortunately it doesn't work. This is sad because what you achieved would be really really great for my open source project www.samplerbox.org.
Could I ask you a favor? Could you try this Raspberry Pi distribution (it's a Debian Jessie, optimized for my software SamplerBox) : http://www.samplerbox.org/makeitsoftware and try if you achieve to do your "magic audio output trick" ?
It would be wonderful for the project SamplerBox : it would allow to have good audio quality without requiring an external USB DAC :)
@josephernest, is your problem resolved ?
No. I havent been able to run successfully the method detailed here.
On Thursday, December 17, 2015, G10DRAS notifications@github.com wrote:
@josephernest https://github.com/josephernest, is your problem resolved ?
— Reply to this email directly or view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-165406138.
I spent 10 days on the issue tried all the solutions, tips and tricks available on internet, but not able to resolve issue. PyAudio recording and playback was working good previously on my Raspberry Pi 2 with raspbian Wizzy. One day I ran sudo apt-get update && sudo apt-get upgrade and next day problem started on my Pi.
Yes, me too. I spent too much days on this issue, it's really annoying. If RaspberryPi cannot provide a decent audio output in the next months, I'll sadly have to move to another platform for my project.
On Tue, Dec 22, 2015 at 4:50 AM, G10DRAS notifications@github.com wrote:
I spent 10 days on the issue tried all the solutions, tips and tricks available on internet, but not able to resolve issue. PyAudio recording and playback was working good previously on my Raspberry Pi 2 with raspbian Wizzy. One day I ran sudo apt-get update && sudo apt-get upgrade and next day problem started on my Pi.
— Reply to this email directly or view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-166498671.
I solved the problem by using the array
module for storing the data.
See here for more info.
Hi guys I see that no one here found the answer for this so far, so after few days of tasting a found the solution for this when opening a new stream you need to set frames_per_buffer to 48000
something like this:
stream = audio.open(format=pyaudio.paInt16, channels=2, rate=RATE_PLAY, output=True, frames_per_buffer=48000)
I hope that will help,
Thanks.
Yes but then, it means that I should real-time resample all my 44.1khz samples to 48khz. This will be CPU-intensive too.
Isn't there a clean way to open a stream in 44.1 khz without having this issue on RPi?
On Wed, Jul 6, 2016 at 1:45 PM, Indigo-Tech notifications@github.com wrote:
Hi guys I see that no one here found the answer for this so far, so after few days of tasting a found the solution for this when opening a new stream you need to set frames_per_buffer to 48000
something like this:
stream = audio.open(format=pyaudio.paInt16, channels=2, rate=RATE_PLAY, output=True, frames_per_buffer=48000)
I hope that will help,
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-230749331, or mute the thread https://github.com/notifications/unsubscribe/AF4eEwddKOFdVgDY-c4tbQgYd6LhoDo4ks5qS5VkgaJpZM4E0c_k .
You can also set it to 44000, and You can try using alsaaudio I moved to it and its working much better for me then the pyaudio.
here are some documentation: http://larsimmisch.github.io/pyalsaaudio/libalsaaudio.html#module-alsaaudio
example for playing a wav file: https://github.com/larsimmisch/pyalsaaudio/blob/master/playwav.py
install it using pip: pip install pyalsaaudio
here how I used it: `device = alsaaudio.PCM() device.setchannels(1) device.setrate(22000) device.setformat(alsaaudio.PCM_FORMAT_S16_LE) device.setperiodsize(320)
data = f.read(320) while data: device.write(data) data = f.read(320)`
when the f is the wav file opened in byte mode.
I needed this to stream the wav file while I read it from url.
@josephernest has your issue been resolved? If so, please close this issue. Thanks.
I'm currently in holidays so I can't check, but in my memories : 44.1khz + RPi + PyAudio (in callback mode) Still doesn't work.
The problem doesn't come from PyAudio/Port audio because this works ok on hundreds of other sound chips.
On Tuesday, August 16, 2016, Rasmus Christiansen notifications@github.com wrote:
@josephernest https://github.com/josephernest has your issue been resolved? If so, please close this issue. Thanks.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-240065718, or mute the thread https://github.com/notifications/unsubscribe-auth/AF4eE5P70j11Ks9tR8XPEYaIuTYzlEDWks5qgZG2gaJpZM4E0c_k .
I tested pyaudio as follows:
Play a wave file (16-bit , Rate: 16000Hz, mono) with
A wave file recorded using pyaudio and play with
I think its an issue with Portaudio as pyaudio is marely a python wrapper for it.
- aplay --- worked.
- play (sox) --- worked.
- pyalsaaudio --- worked.
Are you sure you used them in 'callback' mode (non blocking asynchronous mode) ?
Because when I use PyAudio to play a WAV file in blocking mode, it works (see 'Play' source code in https://people.csail.mit.edu/hubert/pyaudio/, it works ; the one which doesnt work is 'Play (callback)').
I've used portaudio on many projects and many platforms. It always worked, with a large variety audio chips (onboard chips, external USB soundcards, etc.). So I don't think the problem comes from PortAudio.
According to what I read, the problem seems to come when using sndbcm2835 is working in 44.1 khz, because it seems to be ''natively'' in 48khz.
So currently (august 2016), this issue isn't solved : it's impossible to use sndbcm2835 in 44.1khz in callback mode with pyaudio.
On Thursday, August 18, 2016, G10DRAS notifications@github.com wrote:
Play a wave file (16-bit , Rate: 16000Hz, mono) with
- aplay --- worked.
- play (sox) --- worked.
- pyalsaaudio --- worked.
- pyaudio --- Didn't work. Tried pyaudio version 0.2.4, 0.2.8 and 0.2.9 --- same result, sound stuttering
A wave file recorded using pyaudio
- aplay --- worked.
- play (sox) --- worked.
- pyalsaaudio --- worked.
- pyaudio --- Didn't work.
I think its an issue with Portaudio as pyaudio is marely a python wrapper for it.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-240625241, or mute the thread https://github.com/notifications/unsubscribe-auth/AF4eE45tz4m9C-aeNk5TTLjJXojTUHhXks5qg-jrgaJpZM4E0c_k .
I have recorded a wave
(Signed 16 bit Little Endian, Rate 44100 Hz, Stereo) with pyaudio.
pyaudio
in both blocking and non blocking (callback) mode.play(sox)
$ play output44100.wav
File Size: 1.72M Bit Rate: 1.41M
Encoding: Signed PCM
Channels: 2 @ 16-bit
Samplerate: 44100Hz
Replaygain: off
Duration: 00:00:09.75
In:100% 00:00:09.75 [00:00:00.00] Out:430k [ | ] Clip:0
Done.
aplay
$ aplay output44100.wav
Playing WAVE 'output44100.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
PySoundFile
and sounddevice
Now I start using pyalsaaudio
No, this is not correct : if you do it properly, it does work to play a .wav in blocking mode with pyaudio (which is just a wrapper to PortAudio).
As you mention, it works with "aplay" (and all the others you mentioned), but these tools probably use blocking mode as well.
So this is definately not a proof that the problem comes from pyaudio.
On Fri, Aug 19, 2016 at 4:37 AM, G10DRAS notifications@github.com wrote:
I have recorded a wave(Signed 16 bit Little Endian, Rate 44100 Hz, Stereo) with pyaudio.
-
But it didn't play with pyaudioin both blocking and non blocking (callback) mode.
Same wave play with play(sox)
$ play output44100.wav File Size: 1.72M Bit Rate: 1.41M Encoding: Signed PCM Channels: 2 @ 16-bit Samplerate: 44100Hz Replaygain: off Duration: 00:00:09.75 In:100% 00:00:09.75 [00:00:00.00] Out:430k [ | ] Clip:0 Done.
- It play with aplay
$ aplay output44100.wav Playing WAVE 'output44100.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
-
It play with pyalsaaudio
It play with PySoundFileand sounddevice
Now I start using pyalsaaudio
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-240912927, or mute the thread https://github.com/notifications/unsubscribe-auth/AF4eE53e7rZsnxkkb_hQCi6mhjhGXy2bks5qhRcEgaJpZM4E0c_k .
python-sounddevice like pyaudio, is a python binding for PortAudio library, and playback with it is perfectly fine. So it must be pyaudio thats not working as expected.
@G10DRAS, interesting! Can you paste code showing how you did the playback with python-sounddevice, in callback mode?
On Mon, Aug 29, 2016 at 11:05 AM, G10DRAS notifications@github.com wrote:
python-sounddevice like pyaudio, is a python binding for PortAudio library, and playback with it is perfectly fine. So it must be pyaudio thats not working as expected.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-243071604, or mute the thread https://github.com/notifications/unsubscribe-auth/AF4eE7Nt2lL0g5M86pVPe5FDxEv4G36Fks5qkqDJgaJpZM4E0c_k .
See the 'blocking=False
' in play()
import sounddevice as sd
import soundfile as sf
filename = '20seconds_sine.wav'
device=0
dtype = 'int16'
try:
data, fs = sf.read(filename, dtype)
sd.play(data, fs, device=device, blocking=False)
sd.wait()
except BaseException as e:
raise SystemExit(str(e))
This is not a "callback" mode, with a
def audiocallback():
# process an audio buffer of audio
# here return a buffer of 1024 samples for example
On Mon, Aug 29, 2016 at 12:52 PM, G10DRAS notifications@github.com wrote:
See the 'blocking=False' in play()
import sounddevice as sd import soundfile as sf
filename = '20seconds_sine.wav' device=0 dtype = 'int16' try: data, fs = sf.read(filename, dtype) sd.play(data, fs, device=device, blocking=False) sd.wait() except BaseException as e: raise SystemExit(str(e))
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/994#issuecomment-243093062, or mute the thread https://github.com/notifications/unsubscribe-auth/AF4eEzx6N_hVZvU3QvYnmg7j8RjFWrroks5qkrntgaJpZM4E0c_k .
oh you want this....
import sounddevice as sd
import soundfile as sff
duration = 5
filename = '20seconds_sine.wav'
device = 0
dtype = 'int16'
with sff.SoundFile(filename) as sf:
def callback(outdata, frame_count, time, status):
data = sf.read(frame_count, dtype=dtype, out=outdata)
if (data.size != outdata.size):
# zero the part of outdata not written into by sf.read()
outdata[data.shape[0]:,:].fill(0.0)
raise sd.CallbackStop()
with sd.OutputStream(device=device, samplerate=sf.samplerate,
channels=sf.channels,
dtype=dtype,
callback=callback) as ss:
while (ss.active):
sd.sleep(duration * 1000)
It works, you're right! Problem solved after more than one year! This allows a major update for www.samplerbox.org: it now works with RPi's built-in audio chip. Great!
I'm having a problem that I think is very related to this and I haven't been able to solve it. Instead of playing a wav file I want to generate the audio directly in my code. As in the following example:
(source: https://mail.python.org/pipermail/tutor/2012-September/091476.html)
import math
import struct
import pyaudio
def play_tone(frequency, amplitude, duration, fs, stream):
N = int(fs / frequency)
T = int(frequency * duration) # repeat for T cycles
dt = 1.0 / fs
# 1 cycle
tone = (amplitude * math.sin(2 * math.pi * frequency * n * dt)
for n in xrange(N))
# todo: get the format from the stream; this assumes Float32
data = ''.join(struct.pack('f', samp) for samp in tone)
for n in xrange(T):
stream.write(data)
fs = 48000
p = pyaudio.PyAudio()
stream = p.open(
format=pyaudio.paFloat32,
channels=1,
rate=fs,
output=True)
# play the C major scale
scale = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6]
for tone in scale:
play_tone(tone, 0.5, 0.75, fs, stream)
# up an octave
for tone in scale[1:]:
play_tone(2*tone, 0.5, 0.75, fs, stream)
stream.close()
p.terminate()
When I run this on my computer (OS X) it works fine. When I run it on raspberry pi (3, with raspian jessie) I get a stuttery sound output and the following errors:
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused
Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started
I am very new to this and have attempted to solve the problem with the suggestions made in this thread, was however not successful and would really appreciate some help.
The problem was solved by replacing pyaudio by sounddevice module.
I can't get sounddevice to work, when I try to run the code I get the error message: No module named sounddevice My attempts to follow the instructions on this page https://pypi.python.org/pypi/sounddevice/ are leading nowhere. Can you provide me with any help in installing sounddevice?
Just use pyalsaaudio,
its simple as:
import alsaaudio
out_stream = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, alsaaudio.PCM_NORMAL, 'default')
out_stream.setformat(alsaaudio.PCM_FORMAT_S16_LE)
out_stream.setchannels(channels)
out_stream.setrate(rate)
out_stream.setperiodsize(size)
data = file.read(size)
while data:
out_stream.write(data)
data = file.read(size)
apt-get install libasound2-dev
pip install pyalsaaudio
if you have dmix use it.
@Indigo-Tech
Could you please specify your example for the creation of a 100Hz sine wave?
@elanals
import math
import struct
import alsaaudio
def play_tone(frequency, amplitude, duration, fs, stream):
N = int(fs / frequency)
T = int(frequency * duration) # repeat for T cycles
dt = 1.0 / fs
# 1 cycle
tone = (amplitude * math.sin(2 * math.pi * frequency * n * dt)
for n in xrange(N))
# todo: get the format from the stream; this assumes Float32
data = ''.join(struct.pack('f', samp) for samp in tone)
for n in xrange(T):
stream.write(data)
fs = 48000
stream = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, alsaaudio.PCM_NORMAL, 'default')
stream.setformat(alsaaudio.PCM_FORMAT_FLOAT_LE)
stream.setchannels(1)
stream.setrate(fs)
stream.setperiodsize(1024)
# play the C major scale
scale = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6]
for tone in scale:
play_tone(tone, 0.5, 0.75, fs, stream)
# up an octave
for tone in scale[1:]:
play_tone(2*tone, 0.5, 0.75, fs, stream)
stream.close()
@Indigo-Tech Thank you for that, but the problem still remains that the audio output sounds completely wrong and unclean...
@elanals
Are you using the built-in sound device?
@Indigo-Tech yes, I have regular headphones plugged into the headphone jack on the raspberry pi
It seems the problem is in the build in sound card, I tested it now with usb external sound card and it works fine but with the built in one sound unclean as you said.
@Indigo-Tech Would something like this work? https://www.conrad.de/de/71-soundkarte-extern-hama-71-surround-externe-kopfhoereranschluesse-871260.html (sorry that the website is German, but that's the shop I would go buy it from to be able to get it as quickly as possible)
Yes, it should be fine.
Wow, three years and this issue is still not resolved!
This issue is closed. Are you saying this particular issue is still a problem, or you have a different problem?
When using PyAudio with the RaspberryPi's built-in audio
snd_bcm2835
, we get this strange behaviour:This problem doesn't exist when you use an external USB soundcard, a DAC, etc.
How to solve this stuttering problem?
It's very simple to reproduce the error. First you need PyAudio >= 0.2.8 (before, it doesn't support audio out via Callback function). Thus you can't
apt-get install pyaudio
(obsolete). Install PyAudio with:You need to download 20seconds_sine.wav. Then here is test.py (download link here):