PCM driver / ALSA!


13 posts
by lucy » Fri Dec 07, 2012 1:20 pm
Hi!
I am writing a ALSA/PCM driver, started with the playback part. To a certain degree it works , (I am very happy about that because this is the first time I am writing a driver for linux) but...
When I start to playback a stream (a sinewave signal) through aplay then to a codec on the I2S interface and analyze it on a scoop. I can see the sine wave. Unfortunately there are some samples 'disappeared'.
With the result that when I start to play a music stream and record it from the CODEC to a computer (audacity) you can hear the melody of the sound and recognize which song it is but the quality is really miserable!
Besides I get the next warning/error messages:
- snd_pcm_update_hw_ptr0: (a number, for example: 308344) callbacks suppressed
or
- underrun!!! (at least (a number, for example: 144.262 ms) long)
or both...

I think that the timing is not correct. I guess this has something to do with the .pointer and the interrupt function of my alsa driver. (I used the dummy.c file as a starting point of my driver.)

Well, I hope someone with a bit more experience on writing an ALSA driver is on the forum who maybe can give me some hints?

Thanks!
Lucy
Posts: 17
Joined: Tue Oct 02, 2012 2:16 pm
by mhelin » Sun Dec 09, 2012 6:49 pm
Is your implementation based to polling, FIFO IRQ's or DMA? In any cases it may just be that some other process with a higher priority interrupts your process.
Posts: 99
Joined: Wed Oct 17, 2012 7:18 pm
by lucy » Mon Dec 10, 2012 9:32 am
My implementation is passed on DMA (and IRQ of the DMA).
That's a good point I am going to try to set a higher priority for the DMA.

But I interpreted the 'underrun error' as in, the ALSA-LIB cannot deliver samples quickly enough. So.. am I wrong? Is it the other way around? Am I asking too fast too many samples from the alsa-lib?
Posts: 17
Joined: Tue Oct 02, 2012 2:16 pm
by mhelin » Mon Dec 10, 2012 11:42 am
I think the ALSA underrun happens if you application can't supply enough samples to alsa-lib in time. Try increasing buffering (in ~/.asoundrc or using aplay command options). Try increasing priority of your application using nice or renice and give some negative nice value for it.

So it may be that the DMA IRQ already have enough priority. I think USB drivers (including ethernet) though have the highest priority and use FIQ level IRQ. Maybe no need to change anything there.

Btw. have you looked at ALSA SoC drivers? Regarding RPi they might be better solution for the Raspberry Pi community as they already support like a hundred or so CODEC's already.

Some links to ASoC resources:
http://www.alsa-project.org/main/index.php/ASoC
http://opensource.wolfsonmicro.com/cont ... ux-systems
http://omappedia.com/wiki/Audio_Drive_Arch (OMAP specific)

Anyway nice you have started with the driver, now let's get it running..
Posts: 99
Joined: Wed Oct 17, 2012 7:18 pm
by lucy » Mon Dec 10, 2012 12:35 pm
http://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html says: (underrun for playback or overrun for capture). The underrun can happen when an application does not feed new samples in time to alsa-lib (due CPU usage). The overrun can happen when an application does not take new captured samples in time from alsa-lib.

As I read it, I would say that my driver is not the application where they are talking about, because I am just take the samples out the alsa-lib.
BUT if I take the sample out to fast, the alsa-run is in underun? What do you think?

I tried to increase the buffer unfortunately I did not succeed... But I dont think that is the problem.

I took a look (a while ago) at the ALSA SoC drivers, for the CODEC I use (WM8731) is also a SoC driver present. But I am not using it at this moment. I did those few basic settings in my driver, and dont see the advantage to use it at the moment.

Well, I am still struggeling with the underrun error. This very frustrating because I am almost there.. for a while....

mhelin, I really appreciate your response! :)
Posts: 17
Joined: Tue Oct 02, 2012 2:16 pm
by mhelin » Mon Dec 10, 2012 5:29 pm
Your application is for an example aplay if you use aplay to stream sound to the DAC part of the CODEC. Because it is a use space program it is interrupted all the time by the kernel and the interrupt handlers. Try increasing it's priority (use ps aux|grep aplay to get the PID when it's running - you can also try running it as root to see if that helps). Unless some DMA channels have more priority than the others you cannot do anything to raise the priority of your driver. I don't know but it might be possible to request the DMA IRQ as FIQ but I don't think that would help. Got to learn how the DMA works first, sorry can't be much of help before. However, without seeing your source code cannot either help much, so if possible please show it us.
Posts: 99
Joined: Wed Oct 17, 2012 7:18 pm
by gdecarli » Thu Dec 20, 2012 10:33 pm
hi lucy i'm writing the same things as you, but i've started by few day to write code, and i think you have alredy done more work than me, are you interessed to share youre code and work togheder? contact me in private if you are interessed.
P.s.
did you have done any measurement for the jitter on the clock?
P.P.S.
my 2 cent to the thread: I get the Underrun error when my FIFO is empty according to the datasheet of the chip.
Posts: 4
Joined: Wed Sep 05, 2012 4:35 pm
by mhelin » Mon Dec 24, 2012 10:46 am
my 2 cent to the thread: I get the Underrun error when my FIFO is empty according to the datasheet of the chip.


Yes but why does it happen? If the application can't feed enough data to driver, right? Also DMA should take care of keeping the FIFO level above zero if configured properly so the FIFO keeps non-empty but it might be that the next DMA buffer is not filled by application/ALSA when the bufferswitch occurs (when the DMA controller loads the next Control Block and raises an IRQ) . One problem might be the ALSA resampler, see that you use the same sample rate and bit depth that the hardware supports.

http://www.alsa-project.org/main/index. ... evelopment
Posts: 99
Joined: Wed Oct 17, 2012 7:18 pm
by gdecarli » Wed Jan 02, 2013 6:29 pm
mhelin wrote:
my 2 cent to the thread: I get the Underrun error when my FIFO is empty according to the datasheet of the chip.


Yes but why does it happen? If the application can't feed enough data to driver, right? Also DMA should take care of keeping the FIFO level above zero if configured properly so the FIFO keeps non-empty but it might be that the next DMA buffer is not filled by application/ALSA when the bufferswitch occurs (when the DMA controller loads the next Control Block and raises an IRQ) . One problem might be the ALSA resampler, see that you use the same sample rate and bit depth that the hardware supports.

http://www.alsa-project.org/main/index. ... evelopment

are you sure that you are using the resempler? try the snippet in the link you have posted to check...
sorry for the time for answer your question i did not check the forum in the holydays, best regards and let me know.
Posts: 4
Joined: Wed Sep 05, 2012 4:35 pm
by lucy » Thu Jan 24, 2013 12:46 pm
Hi all,
I am still struggling with a timing problem in my driver. I added some images to clarify.
When I play back an example wav (A sinus of 100Hz for 0.4s and 0.6s of silence) and measure it with a scoop I see this:

image13195.png
not correct signal
image13195.png (33.6 KiB) Viewed 3789 times
,
image2003.png
not correct signal, zoom
image2003.png (40.89 KiB) Viewed 3789 times


As you can see there are some spikes and zero where they shouldn’t be.
When I keep the CPU busy by for example pressing the enter button, then I see this:

image6281.png
How it should be
image6281.png (30.66 KiB) Viewed 3789 times


This is how it always should be.
So my conclusion is: timing problem.
Now the solution...?

Some things I tried:
- Increase/decrease the period time
- Increase/decrease the buffer size
- Configuring the dma in several ways.

Notes:
- In my driver I fixed the sample rate which corresponds with the sample rate of the wav file.
- I move the data from the alsa buffer with DMA to the PCM FIFO
- I have the same problem with recording data.

Until now I couldn’t detect in which part (dma/ISR/../..) the problem is.
Maybe someone with some more (sound driver) experience can give me a hints?
Posts: 17
Joined: Tue Oct 02, 2012 2:16 pm
by mhelin » Fri Feb 15, 2013 9:54 pm
As you can see there are some spikes and zero where they shouldn’t be.
When I keep the CPU busy by for example pressing the enter button, then I see this:
How it should be


Now don't know if anyone has thought it before, but is it possible that some power saving feature kicks in and distorts the audio unless you "keep the CPU busy"? For an example are there any kernel options which by default are turned on? It might be possible VideoCore firmware has some built-in powersaving which isn't possible to control at all.
Posts: 99
Joined: Wed Oct 17, 2012 7:18 pm
by ppuskari » Sun Feb 17, 2013 6:12 pm
Interesting. By default do you have any of the cpu overclock settings enabled? If you do not and are running stock then you might definitely take a look at the config.txt option that removes the automatic speed ladder control. Could be that you are only getting the right sound output when the cpu is forced to the higher rate but when the firmware/kernel? drops you back to 700mhz or when it pushes up you get the waveform anomaly.

I think the option is still called and will turn off the dynamic clocking.

force_turbo=1
Posts: 38
Joined: Sat Jul 07, 2012 4:04 am
by ersten » Fri Mar 14, 2014 7:41 pm
Did you find a solution to this problem?
I try to launch sdr-radio on RPI. And I have same troubles - aplay underruns when CPU not loaded. Though when I busy CPU to 100% load (just runs "tar" on another session) underruns almost disappears.

Thread for SDR-radio on this forum: viewtopic.php?f=41&t=11542
Sorry for my bad English, I still learning.
User avatar
Posts: 2
Joined: Sat Mar 08, 2014 3:14 pm
Location: Russia, Tver