Closed PaulWieland closed 3 years ago
I believe this is some sort of a problem with pyaudio (or even portaudio), but I cannot figure it out. I can't get pyaudio to output any sound under docker on my raspberry pi 4.
I created a new docker image that only installs the libraries and then attempts to play a wav file using the example script from the pyaudio home page. This doesn't produce any sound, however aplay
works just fine.
Then then tried compiling portaudio and running the test/patest_sine8.
program - (which I am blindly assuming outputs a sine wave sweep) which also produces no sound.
Stuck.
Probably portaudio - I think portaudio is intended for macOS only. Could be wrong.
Well, doesn’t the receiver script rely on pyaudio to output sound (regardless of OS)?
from what I understand pyaudio is a python wrapper for portaudio.
I was completely wrong XD - PortAudio is cross-platform 🤦
I built a test dockerfile that does the bare minimum. It's built on the official python3 image and it uses the demo play.py file from pyaudio. No sound.
I'm currently also having this issue @PaulWieland do you have this fork working outside of docker? Also I have tried on macOS Big Sur with no luck (however due to Big Sur being different in lots of ways I kind of expected that)
@M-Whitaker I can't get a RaspberryPi to output sound correctly with pyaudio (see my pyaudio_test container in the previous reply). Docker or not doesn't seem to matter.
From what I understand, the docker container is incompatible with macOS because it expects to output to /dev/snd
- which is normal for Linux but not for macOS.
The ap2 receiver does work on macOS if you run it natively using the instructions in the Readme.
Ah perfect thanks for the clarification. For information I was using the native install for macOS Big Sur as like you I noted the /dev forwarding wasn't going to work. What devices have you got this working on? as I'm slightly confused as to what is working and what shouldn't as I understand this is a POC.
I'm running the receiver under 10.15.7 (I haven't updated to Big Sur yet because of compatibility issues with my company's VPN).
Tested Clients:
This combination works perfectly fine for me.
Ok, thanks for that as said it is really not a surprise that Big Sur breaks things (I'm also running M1 but that shouldn't effect anything from what I have seen skimming the code). I have to say on the docker/portaudio front I haven't previously tried running audio applications though docker as I know getting devices & drivers to work this way can be a pain. Would be interesting to see if #9 works (i.e. not using docker) on your setup as I couldn't get past an error: amixer: Unable to find simple control 'PCM',0
The program should not be trying to call amixer
under darwin (macOS).
Can you run a quick test to verify what python thinks your OS is?
Go to a terminal and type in python3
and press enter. Now type in the following two lines:
import platform
platform.system()
It will output your system name, which if you are on a mac should be 'Darwin'.
Sorry, this is on my PI4. (My Mistake)
Ok, in that case you need to find out what the alsa device name is (which can be different on each machine - which is why ckdo added the --no-volume-management flag).
On mine it's Headphone (not PCM).
So the solution is to run it without volume management - or or to modify the get/set_volume subroutines in the utils.py
script.
Launch a container and jump into the shell:
docker run -it --rm --device /dev/snd --net host invano/ap2-receiver /bin/bash
Then type amixer scontrols
and it should tell you what your mixer name is.
Then modify utils.py
accordingly:
Get Volume becomes:
line_pct = subprocess.check_output(["amixer", "get", "Headphone"]).splitlines()[-1]
Set Volume becomes:
subprocess.run(["amixer", "set", "Headphone", "%d%%" % pct])
Thanks, that was a bit simple of me... Shouldn't have skipped over that. So this is now working the same as the docker container (no audio) which I assume is the same place you are on your PI4?
Correct. The client can connect and play/pause/disconnect/reconnect/adjust volume. But there's no sound. I'm trying to get help from the port audio mailing list, because I believe this is an issue with that library. The python script is using pyaudio (which depends on portaudio).
My pyaudio_test was an attempt to isolate the problem.
@PaulWieland I'm testing it currently with Docker on Debian Buster (kernel 4.19) and it works if I use --privileged
for the audio device. I know --privileged
isn't a (nice) solution, but it helps to narrow down the error further. I will do some tests on the weekend and maybe I'll find the cause and a nice solution :)
A small update. I replaced portaudio with alsa and everything works fine.
https://github.com/PaulWieland/airplay2-receiver/blob/alsaaudio/ap2/connections/audio.py
I’m sure this change breaks cross platform support but shairport-sync writes directly to alsa as well so...
@ all : Do not forget, to work with the upstream...
@Neustradamus > @ all : Do not forget, to work with the upstream...
Please stop with this.
A small update. I replaced portaudio with alsa and everything works fine.
@PaulWieland sounds great! I've tested to build the container from your alsaaudio
branch, but it fails while step 6 Installing build dependencies
. anything I need to change for the build?
docker build -f docker/Dockerfile -t invano/ap2-receiver .
@satrik I'm working on optimizing the dockerfile into a multi stage build so the image is a little smaller. You can use your existing image with the python code from the alsaaudio branch.
The volume flag will start the container and map the repo on your host to the /airplay2
directory in the container. That way you can modify the python code and test the changes without rebuilding.
e.g. clone and then checkout the branch, in your home directory and then start the container:
run -it --rm --device /dev/snd -v ~/airplay2-receiver:/airplay2 --env AP2IFACE=eth0 --net host invano/ap2-receiver
I hope to get the dockerfile working soon, but try the above if you are impatient :)
@satrik I just got around to building/testing the docker image in my alsaaudio branch. It works perfectly well on my rpi4 with 2gb of ram. However, I only managed to get the image down to 445mb.
@PaulWieland nice, I will try it out in the days :)
if this works now, than we just need to figure out how the HomeKit pairing works and implement it^^
Closing, since replacing pyaudio with pyalsaaudio solves the issue.
@PaulWieland - could you give portaudio 19.7 a try, and see whether any of the newer fixes resolve your audio issue, please?
@systemcrash I had tried 19.7 when it first released at the advice of the portaudio devs - it didn't work. But now that shairport-sync supports airplay 2 it doesn't really matter...
I’m just testing out the docker image on my raspberry pi 4 and for some reason I am not getting any sound output.
The client (iOS 14.4) connects and I see what looks like audio being buffered in the container log, but I have no audio coming from the 1/8” port on the pi.
I tested
aplay
a wav file locally to make sure there isn’t something wrong with my pi and it seems to work just fine.I’m really interested in this project. It would be excellent to have a basic airplay 2 receiver for multi room audio with the pi acting as a receiver and a digital signal processor for DML speakers.
UPDATE: I ran
docker run -it --rm --device /dev/snd --entrypoint /bin/bash invano/ap2-receiver
to get to the containers shell, and then ranspeaker-test
. This is producing static on the pi's headphone jack, which tells me that the the hardware + docker are all working just fine.