alsa-project / alsa-lib

The Advanced Linux Sound Architecture (ALSA) - library
GNU Lesser General Public License v2.1
354 stars 177 forks source link

snd_pcm_readi() takes to much time. #270

Open coder0201200 opened 1 year ago

coder0201200 commented 1 year ago

I am using alsa open source library for my project to read and write audio data.

For that I am using snd_pcm_readi function to read audio data. I am able to read audio data.

But issue is that sometimes it will take so much time to read data.(200-230 msec). Normally this function executed in 1-3 ms that is normal case, but after every 2-4 frames it is taking 200-300 msec. So this is affecting my whole application process.

I have also try to set this call as nonblock with the help of snd_pcm_nonblock function. With that I have observed some improvements but still after 2-3 frames it is taking 100msec time to get a data.

perexg commented 1 year ago

From the first glance, the timing depends on the hardware parameters and also on the driver position update granularity. Which driver are you using? Could you show dump of parameters using snd_pcm_dump() function ?

coder0201200 commented 1 year ago

Please find HW params and SW params which is dumped using snd_pcm_hw_params_dump and snd_pcm_sw_params_dump

HW params: ACCESS:  RW_INTERLEAVED FORMAT:  MU_LAW SUBFORMAT:  STD SAMPLE_BITS: 8 FRAME_BITS: 8 CHANNELS: 1 RATE: 48000 PERIOD_TIME: 125000 PERIOD_SIZE: 6000 PERIOD_BYTES: 6000 PERIODS: 4 BUFFER_TIME: 500000 BUFFER_SIZE: 24000 BUFFER_BYTES: 24000 TICK_TIME: [0 0]

SW params: tstamp_mode: NONE tstamp_type: GETTIMEOFDAY period_step: 1 avail_min: 6000 start_threshold: 24000 stop_threshold: 24000 silence_threshold: 0 silence_size: 0 boundary: 6755399441055744000

perexg commented 1 year ago

The period_size determines the wake-up latency for the blocking I/O mode. For rate 48000Hz and period size 6000 frames is the wake-up time 6000/(48000/1000) = 125ms. For the non-blocking I/O mode the granularity is determined by the hardware capabilities (the ring buffer pointer updates in the driver) and the avail_min settings (sw_params) when you use an event multiplexing call (select or poll).

EDIT: You did not write anything about used hardware / audio driver to check the ring buffer pointer granularity.

coder0201200 commented 1 year ago

How can I find the ring buffer pointer updates in the driver ? And can i change avail_min time for non-block mode ?

coder0201200 commented 1 year ago

I am using HW ambarella cv25 and audio is ak4951.

coder0201200 commented 1 year ago

@perexg any update on this. Please help me to resolve this issue.

perexg commented 1 year ago

Could you test your code with the standard PC hardware ? It appears that the audio driver has some issues for this special SoC platform.

avail_min - https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___s_w___params.html#ga79b12cbbd309750156261e7f5a39167b