PortAudio / portaudio

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

Signal errors after long data acquisition #705

Open goranobradovic1 opened 2 years ago

goranobradovic1 commented 2 years ago

Hello

We use PortAudio in our application for data acquisition from sound cards.

Environment:

The tests were done by using various sound cards, for example Behringer UMC1820 (USB), Echo AudioFire12 (Firewire). We used both DirectSound and ASIO drivers. We tested with Windows 7/10/11.

Problem:

After a very long acquisition, for example ~6h with 2 channels @48000Hz sample rate, we start observing errors in the acquired signal. It seems that signal blocks are misplaced and blocks from channel 1 are occasionally delivered for channel 2 and vice versa (tested with signal generator generating sweep signal). After restarting acquisition the signal is fine again, and starts delivering errors after exactly the same time. Tests with different sampling rates and number of channels seem to show that the errors always start after 2^31 (MAX_INT) acquired samples (sum over all channels). Since our application does not count samples in any way, maybe the problem is inside PortAudio?

We have the same problem with all devices we've tested and with both DirectSound and ASIO.

Here is an example of the signal error: error1

Best regards Goran Obradovic

RossBencina commented 2 years ago

Hi There. Phil and I have done a preliminary code review and haven't found anything obvious, which is not to say there is not a problem in PortAudio. I have some questions for clarification:

Do you observe continuous ongoing glitches, or just one glitch at ~6h?

What is the duration of the glitch, in samples/frames? Is it consistent between all failures? Is it related to the callback buffer size that you are using? Does it vary with requested latency/host buffer size? If possible, try different callback sizes please.

To be clear, is this bug happening on all combinations of Windows 7/8/10, ASIO/DirectSound and Behringer/Echo?

It would help to know whether there are host APIs that it doesn't happen on. Could you try WMME and WASAPI please?

goranobradovic1 commented 2 years ago

Hi

Thank you for a fast response.

Here are the answers to your questions:

Do you observe continuous ongoing glitches, or just one glitch at ~6h?

We observe continuous glitches after they start (multiple glitches per second).

What is the duration of the glitch, in samples/frames? Is it consistent between all failures? Is it related to the callback buffer size that you are using? Does it vary with requested latency/host buffer size? If possible, try different callback sizes please.

It is always exactly the length of the callback buffer.

To be clear, is this bug happening on all combinations of Windows 7/8/10, ASIO/DirectSound and Behringer/Echo?

Yes

It would help to know whether there are host APIs that it doesn't happen on. Could you try WMME and WASAPI please?

Unfortunately, our application uses PortAudio only for DirectSound and ASIO. For MME, we have our own implementation where we do not observe these problems.

Best regards Goran Obradovic

RossBencina commented 2 years ago

Do you know what the host buffer sizes are? (e.g. are you using host-specific extensions to set host buffer sizes, or are you just specifying a latency to PaOpenStream?)

What host buffer sizes or latencies are you specifying?

What callback buffer size(s) are you specifying?

goranobradovic1 commented 2 years ago

What host buffer sizes or latencies are you specifying?

I am not using any host-specific extensions to set host buffer sizes. "suggestedLatency" is set to Pa_GetDeviceInfo( device )->defaultLowInputLatency

Callback buffer can be set by the user, common setup would be 4096 samples @ 48kHz.

philburk commented 2 years ago

4096 frames seems very large for a callback buffer. That may be inviting some internals buffers to overflow.

If you are recording audio and then writing it to a file then you might consider using blocking reads with a large buffer. This can be done in the same thread that does the file writes.

Or you can use a smaller callback size and write data into your own big FIFO. Another thread can read that FIFO and do the file writes.

dechamps commented 2 years ago

4096 frames seems very large for a callback buffer. That may be inviting some internals buffers to overflow.

Wouldn't that qualify as a PortAudio bug? Isn't PortAudio supposed to do automatic buffer adaptation? As a user, if I pass a large buffer size, I would naturally expect PortAudio to use smaller internal buffers if necessary and read/write the user buffer in small chunks. Isn't that currently the case?

philburk commented 2 years ago

Wouldn't that qualify as a PortAudio bug?

Yes. But if you tried these things and it fixed the problem then it would give us two things:

  1. We would learn something about the nature of the bug in PortAudio.
  2. You would have a workaround until we fixed the bug.

When developing software we try to test the common use cases. Very long recording times often do not get tested well because it is not a common use case and it takes a long time to test. We also may only be testing smaller callback sizes.

RossBencina commented 2 years ago

@goranobradovic1 are you consuming/using any PortAudio-generated timestamps?

RossBencina commented 2 years ago

@goranobradovic1 We're happy to help with ideas, but I don't think Phil and I have the resources to really dig into this gratis at the moment. I don't think we can fix this without reproducing the issue. The next step would be to rework the PA loopback test to run for 12 hours and see whether (a) you can reproduce the issue (b) we can reproduce the issue, outside your application. Then we will have a better idea where to look. You could do this work, or I might some availability to work on debugging this issue as a paid project -- if that's within your means, please email me at rossb@audiomulch.com.

goranobradovic1 commented 2 years ago

@RossBencina Thank you for investing your time and looking into this. We are currently investigating some workarounds (stopping/starting data retrieval after some time) to see if works. Depending on the result, we will decide about the priority of this problem and consider further steps. Also, we will do some more tests - maybe it will bring some new valuable information. I will let you know as soon as I have new information.