I have an application based on Juce that already runs fine on Windows and OS X and I am trying to make it run on Linux distribution, on a Raspberry Pi 2 (I am currently trying on a Debian).
I want to use it with an USB Audio Class 2 device. The application opens input and output channels as well (it has to run fine on 6 channels).
The problem on Linux is that after a while the sound becomes distorted. It plays fine for some time (from a few seconds to a few minutes and then the sound becomes distorted). I also tried with a simple app (let's call it DEMO) which contains only an AudioDeviceSelectorComponent where I route the input to output and I have the almost the same result. The difference is that the sound is more stable (distorsion appear later). The problem does not seem to be related to the audio buffer size. With DEMO I can play fine for over an hour with 96000Hz and 256 samples buffer and I can hear distorsion after just a few seconds with 48000Hz and 512 samples buffer.
The problem seems to me to be somehow related to CPU usage. I tried with 3 apps: my full application, my application without gui (but does the whole processing part) and that DEMO. With applications that take more CPU, the sound becomes unstable sooner (my full app - gui and processing - runs fine from only a few seconds to a few tens of seconds while my app without gui can run fine up to an hour with 5ms buffers). However, with the same application, things are confusing. With a smaller buffer (which implies higher CPU usage) the app can run better than with larger buffers.
I also tested my app on a laptop running Ubuntu 14.04 and I get the same results (with the difference that the apps can play fine longer until the distorsion appear).
I noticed that while the sound is distorted, if I change device parameters (sample rate or buffer size) the sound becomes normal (for an amount of time, but distorsion appears again after a while).
ALSA does not report any xrun while this is happening (at least this is what I think, I put 3 in /proc/asound/<mycard>/pcm0p(c)/xrun_debug and I see nothing in the logs) and the signal is already distorted when I read it from the input buffer.
If someone has any clue on how to debug this or what can I try to fix this problem please let me know.
We've had a very similar problem with ALSA audio, which I think we fixed by changing the thread schedule priority of the ALSA thread - but I need to get in touch with the engineer that worked on that specific problem to double check.
Are you also using a USB audio device when running on your laptop? If yes, can you try this with a "real" audio device? I know that the kernel handles USB audio devices quite differently - for example - it is not possible to directly memory map the audio buffer of a usb device. Obviously, JUCE should also run on usb audio devices but it would help narrow down the problem.
Yes, on the laptop I tried with the USB device too. It was a XMOS Multichanel Reference Design (the same device that I use in most of the tests on the RPi).
What do you mean when you say a ”real” audio device? If I used ALSA_Soundcards instead of ALSA_PCMDevices? If this is what you meant, I used both of them with the same results.
With "real" device, I was referring to your laptops internal soundcard. For example, for PCI sound devices, I think ALSA directly maps the hardware audio buffer so that the user has the lowest possible latency. This is not possible with USB devices and therefore ALSA treats them differently internally.
I've spoken with our engineer here and unfortunately he hasn't encountered your specific problem. However, he did say that thread/task priorities could make a big difference. Have you tried playing around with
setThreadPriority? Also, you may want to try to start your process with a lower "nice" value. We've also found that tools like htop really help to debug thread performance issues. Also, be warned that increasing the thread priority (or decreasing the niceness) too much will also cause problems, as the ALSA kernel thread will not have enough priority to run smoothly.
No, I didn't try the internal soundcard. It has only 2 channels and I thought the test is not relevant. However, I will try to make the tests with that soundcard and stress the app with different sample rates and buffer sizes to see how the behaviour compares to the usb soundcard.
The alsa tread has priority=9 which I thought should be enough, given that I do not have any other threads in my simple demo app.
Playing around with "nice" seems to make the sound a bit more stable. I will try to find a combination for which the app works fine.
I use htop to monitor the cpu usage but I didn't figure out how to use it to find out what is blocking my audio thread.
I will come back with further results after I do some more tests.
I am back later than I hoped. However, I managed to run more tests and results are the same. "nice" doesn't seems to solve the problem, nor playing around with thread priority. I also tried to set the scheduling policy to SCHED_FIFO, but I didn't see any impact of using this over SCHED_RR.
I am not very familiar with linux programming, nor with ALSA, so this can be a silly question, but couldn't it make a difference setting the access type of the pcm one of the MMAP types? Like SND_PCM_ACCESS_MMAP_INTERLEAVED for instance. I might give it a try with this but first it would be useful to hear some opinion about this.
Have you tested it with the internal sound card yet? I'm just a bit worried that this may be a sound driver issue rather than ALSA and/or JUCE. After all, Linux is a bit notorious for subtle driver bugs - for instance my sound card needs two reboots after a sleep to work without clicking.
I get the same results (a lot of crackling as if buffer dropouts occur) on a Ubuntu 14.04 with a Intel onboard card using default values set by the JUCE Demo app (buffer size is set to 512). Either playing the sine wave sound or the sampled sound i get a lot of distortion. Is there any fix for this ?