Reputation: 375
I'm currently experimenting with real-time signal processing, so I went and tried out PortAudio (from C).
I have two audio interfaces on my computer, onboard sound (Intel HD Audio) and a USB audio interface. Both generally work fine under ALSA on Linux. I also tried the USB audio interface under JACK on Linux and this also works perfectly.
What I do:
My code just initializes PortAudio, opens and starts a stream (one channel, paInt32
sample format, defaultLowInputLatency
/ defaultLowOutputLatency
, though I tried changing to paFloat32
or defaultHighInputLatency
/ defaultHighOutputLatency
, which didn't improve anything).
On each invocation of the callback, it copies sizeof(int32_t) * frameCount
bytes via memcpy
from the input to the output buffer, then returns paContinue
. It does nothing else in the callback. No memory allocation, no system calls, nothing it could block on. It just outputs what it has read. The code is very simple, still I can't get it running.
Replacing the memcpy
with a loop copying frameCount
elements of type int32_t
over from the input to the output buffer didn't change anything.
What I've tried:
The following scenarios were tried out with PortAudio.
The problems I encountered:
The results were as follows. (Numbers represent the scenarios described above.)
Between each try, ALSA has been tested if it's still responsive (sometimes it got completely "locked up", so that no application could output sound any longer) and rebooted the system in case ALSA got "locked up", then continued the testing.
More details, that might be useful when tracking the problem down:
In the scenarios where there is no output at all, I get the following error messages when using ALSA as backend.
Expression 'err' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3350
Expression 'ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3876
Expression 'PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 4248
I get the following error message when using JACK as backend.
Cannot lock down 42435354 byte memory area (Cannot allocate memory)
In addition, no matter what method I use, I always get these warnings.
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
When using ALSA, I also get one or two complaints about underruns.
ALSA lib pcm.c:7905:(snd_pcm_recover) underrun occurred
The PortAudio functions that I call (Pa_Initialize
, Pa_OpenStream
, Pa_StartStream
, Pa_StopStream
, Pa_CloseStream
, Pa_Terminate
, in this order), all return paNoError
.
The paex_read_write_wire.c
(blocking I/O) example that comes with PortAudio can usually access the device, but also experiences lots of underruns (like my test case 2).
In either case, there's nothing interesting showing up in dmesg
. (Just checked that, since ALSA has a kernel-level component.)
My question:
Anyone knows what's the problem here and how I could fix it? Or at least, how I could narrow it down a bit more?
Upvotes: 4
Views: 2834
Reputation: 31
I'm unclear on the details, but for me switching from default low input/output latency to default high input/output latency cured this problem, and I can't perceive a change in latency.
Upvotes: 0
Reputation: 180310
When you write only a single block of samples, the playback device will run out of samples just when you're about to write the next block.
You should fill up the playback device's buffer with zero samples before you start the read/write loop.
Upvotes: 1