4

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.

  1. Input and output via USB audio interface, callback mechanism on PortAudio, ALSA backend.
  2. Input and output via USB audio interface, blocking I/O on PortAudio with 1024 samples buffer size, ALSA backend.
  3. Input via USB audio interface, output via onboard sound, callback mechanism on PortAudio, ALSA backend.
  4. Input via USB audio interface, output via onboard sound, blocking I/O on PortAudio with 1024 samples buffer size, ALSA backend.
  5. Input and output via USB audio interface, callback mechanism on PortAudio, JACK backend.
  6. Input and output via USB audio interface, blocking I/O on PortAudio with 1024 samples buffer size, JACK backend.

The problems I encountered:

The results were as follows. (Numbers represent the scenarios described above.)

  1. No output from device.
  2. Output from device unsteady (interrupted). All the time lots of buffer underruns.
  3. No output from device.
  4. Output from device unrealiable. Sometimes it works, sometimes it doesn't. (Without changing anything, just running the executable multiple times.) When it works, latency starts off low, but increases over time and gets very noticeable.
  5. No output from device.
  6. No output from device.

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?

no.human.being
  • 365
  • 3
  • 9
  • Please show your code. – CL. Feb 11 '16 at 09:24
  • Here you go! Thanks a lot for your time and efforts! /// PortAudio (callback-based): http://pastebin.com/MrHpkXEA /// PortAudio (blocking I/O): http://pastebin.com/MDdUZ8W3 /// RtAudio (callback-based): http://pastebin.com/YCQ0JpSR – no.human.being Feb 11 '16 at 17:30
  • FWIW, I get the same trouble on Ubuntu 16.04.1 with a simple PortAudio application. I get this error intermittently. Very frustrating indeed! – Chris Merck Dec 12 '16 at 20:34
  • I'm having similar problems with pyaudio on rasberian. Testing with the suggested answer of adding empty frames. – www139 Nov 24 '19 at 18:41

2 Answers2

1

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.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • Thanks! Are you sure this is how it works with PortAudio? It's a realtime API. The callback gives you an input and an output buffer and a number of frames and (as far as I understand) expects you to read EXACTLY this number of frames from the one and write this number of frames to the other. I expected the API to call me on each block, then output what I've written into the output buffer just after I return. (So call on each block and 1 block "delay" as the block I process is always output in the next iteration.) This is also how it's done in examples. I don't think there's a buffer involved. – no.human.being Feb 10 '16 at 12:18
  • In theory, the realtime API should take care of that. Do PortAudio's example programs work? – CL. Feb 10 '16 at 12:37
  • Like I said, I tried the `paex_read_write_wire.c` example (since, like my application, it does both input and output, but it uses blocking I/O). It doesn't "drop out" like mine, but it underruns all the time and output is grossly distorted. There's sample code in `paex_saw.c`, that outputs a sawtooth wave using callback mechanism (but has no input) and this works on the onboard sound (but also outputs ALSA warnings about "no channel map"), but causes lots of underruns (and distortion) on the USB interface. Note that the USB interface works fine with "normal" applications under ALSA. – no.human.being Feb 10 '16 at 13:00
  • If PA does not work in the first place, there's nothing your program can do. – CL. Feb 10 '16 at 13:04
  • So the library itself is broken? (Ain't that unlikely given that it's pretty common?) What should I do? Try **yet another** library? I just came from "plain ALSA" where I had severe latency problems so people told me to use a callback-based API. (Also, ALSA contains bugs. Already stumbled upon them, but "worked around". ;-) ) I did some research and found that PortAudio seems to be pretty widely used and is designed for realtime processing (which suits my needs). I'd like to develop some audio processing algorithms, yet all I'm dealing with are broken APIs. :-( – no.human.being Feb 10 '16 at 13:09
  • The ALSA bugs mentioned in [your earlier question](http://stackoverflow.com/q/34619779/11654) are actually bugs in Python, or `alsaaudio`. You should probably use another language. – CL. Feb 10 '16 at 13:12
  • Well, I already tried both C and C++. rtAudio also gives me problems. Problem here (apart from the weird circumstance that my primary audio device gets enumerated as ID 4) is: It seems to be alternately reading and writing. I get distortion. When I make the buffer large, I can hear that it "switches on and off". Latency appears to remain constant though. Now I have three libs that apparently don't work. Some problem with my machine/OS perhaps? – no.human.being Feb 14 '16 at 13:56
  • Other programs work on your machine, so I'd guess the problem is in your code. – CL. Feb 14 '16 at 14:49
  • My code is pretty minimal though. Did you have a look at it? I mean the example programs don't work either. My algorithms work when being run on audio files, I just can't get the I/O running for actual hardware. It's pretty important that I can somehow get the I/O done though. – no.human.being Feb 15 '16 at 01:16
0

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.

CodeSoda
  • 31
  • 3