PortAudio / portaudio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.
Other
1.39k stars 291 forks source link

GetExactSampleRate() failures on ALSA #860

Open JoelCJordan opened 8 months ago

JoelCJordan commented 8 months ago

When using ALSA on Linux, sometimes GetExactSampleRate() in pa_linux_alsa.c will fail because snd_pcm_hw_params_get_rate_numden() returns an invalid argument error code (EINVAL or -22). This causes many audio devices to not be detected when initializing PortAudio.

The documentation of this function specifies that this will occur if snd_pcm_hw_params() is not called first. Otherwise, the call to snd_pcm_hw_params_set_rate_near() used to set the sample rate is apparently not sufficient to constrain the configuration space on all systems.

I was able to fix the problem by adding ENSURE_( alsa_snd_pcm_hw_params( pcm, hwParams ), paUnanticipatedHostError ); immediately before both lines which call GetExactSampleRate().

To Reproduce Install Raspberry Pi OS 11 Lite 64-bit on a Raspberry Pi 4B. Run any PortAudio application.

Expected behavior Headphone jack should be in the device list.

Actual behavior Headphone jack is rejected from device list due to error in GetExactSampleRate().

Desktop (please complete the following information):

Additional context I have tried various workarounds, including using a "plug" plugin wrapper. However, this fails due to a later check on the maximum number of channels.

It's possible that using PulseAudio instead of ALSA masks the problem, in which case it would only be seen on the "Lite" release with no GUI.

RossBencina commented 7 months ago

Thanks for finding this. Unfortunately we don't really have anyone who understands ALSA configuration space and how PortAudio is using it so it's difficult for us to assess the fix. For example, is it always safe to constrain the configuration space by calling alsa_snd_pcm_hw_params? Phil is going to look into this.

philburk commented 1 month ago

I booted an RPi4 running Raspbian Linux neuhaus98 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux

entered:

cd portaudio
./configure && make
bin/pa_devs

and got the attached output; pa_devs_dump.txt

The headphone jack was listed. I did not see the error about GetExactSampleRate().

I connected headphones to the RPi4 board and entered: bin/paex_sine

I got a very noisy sine wave on the headphones.

Even though I cannot reproduce this, we should probably add the calls to snd_pcm_hw_params() because of the documented requirement.

philburk commented 1 month ago

I installed the 64-bit version of OS Lite on a flash card. I installed git using: supo apt install git I made the font bigger using: sudo dpks-reconfigure console-setup According to "./configure" ALSA and PulseAudio are not installed. But "aplay" installed!

Using OSS, bin/pa_devs says there are no devices.

I plugged in headphones to the 3.5mm jack and ran: speaker-test -c2 I then heard pink noise on both channels of the headphones.

Why isn't PortAudio ./configure seeing ALSA?

philburk commented 1 month ago

Apparently ALSA drivers are installed but not the ALSA developer libraries. I entered: sudo apt-get install libasound2-dev ./configure && make and could see that ALSA was detected.

bin/pa_devs listed 3 device, the bcm2835 headphones, my hdmi monitor, dmix.

philburk commented 1 month ago

The headphone jack was in the device list. So I am assuming the RPi folks fixed something.

But we should still make the suggested change.

philburk commented 1 month ago

@JoelCJordan - I notice you were using PortAudio 19.6.0. That is quite old. Could you please try your test using 19.7.0 or, even better, the latest code from GitHub.

I will rerun my tests and report the exact OS version I am using.

RossBencina commented 1 month ago

Phil and I discussed the code, and here are my thoughts:

Not to say that will work of course.