Problem with i2s driver and ALSA, underrun
-
My hardware i2s driver's params:
static struct snd_pcm_hardware ralink_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE,
.channels_min = 2,
.channels_max = 2,
.period_bytes_min = PAGE_SIZE, \ 512
.period_bytes_max = PAGE_SIZE * 2, actually not max, it can be PAGE_SIZE * 8
.periods_min = 2, actually idk what this param means
.periods_max = 128, should I enlarge it?
.buffer_bytes_max = 128 * PAGE_SIZE * 2, should I enlarge it too?
.fifo_size = RALINK_I2S_FIFO_SIZE, it's 32
}
static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = {
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
.pcm_hardware = &ralink_pcm_hardware,
.prealloc_buffer_size = 256 * PAGE_SIZE, And enlarge it?
};I have underruns when just aplay 96/24 and 192/24 audio, it s clear with 48/24
root@OpenWrt:~# aplay 24x192.wav -v
Playing WAVE '24x192.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
Plug PCM: Linear conversion PCM (S24_LE)
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S24_3LE
subformat : STD
channels : 2
rate : 192000
exact rate : 192000 (192000/1)
msbits : 24
buffer_size : 96256
period_size : 1024
period_time : 5333
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 1024
period_event : 0
start_threshold : 96256
stop_threshold : 96256
silence_threshold: 0
silence_size : 0
boundary : 1577058304
Slave: Hardware PCM card 0 'ad1938' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S24_LE
subformat : STD
channels : 2
rate : 192000
exact rate : 192000 (192000/1)
msbits : 32
buffer_size : 96256
period_size : 1024
period_time : 5333
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 1024
period_event : 0
start_threshold : 96256
stop_threshold : 96256
silence_threshold: 0
silence_size : 0
boundary : 1577058304
appl_ptr : 0
hw_ptr : 0
root@OpenWrt:~# cat /sys/kernel/debug/10000a00.i2s/stats
tx stats
below threshold 2276321
under run 94
over run 0
dma fault 0Mb I need to change something in my hardware i2s driver?
-
Ok I add some fixes, now it works better, but not perfect on 192/24.
First, I increased period_bytes_max, it can be 65535 bytes cause it limmited only by dma transfer.
Second, buffer_bytes_max and prealloc_buffer_size, I increased them too, now it ~4MB.
Third, dma_data->maxburst = 4, cause it can be transferred 16 bytes, after threshold reached.Now it's randomly can be ~100 underruns while playing, but most od the time it's clear
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3262.796745] underrun 4
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3278.822202] underrun 69
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3291.029872] underrun 19
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3303.158453] underrun 3
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3316.406874] underrun 1
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3328.456432] underrun 1
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3341.206080] underrun 100
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3352.909575] underrun 1
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3365.469447] underrun 0
root@OpenWrt:/# aplay /root/1kHz(24x192)cut.wav
Playing WAVE '/root/1kHz(24x192)cut.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Stereo
[ 3388.133126] underrun 1
-
Now I wanna pre-allocate contiguous block of memory for this DMA audio buffer, cause I think this random can be in slow buffer pushing. I think so, cause of it no underruns on ALSA level, I already debugged it.
-
This can cause stale mixer devices to appear. With mplayer and 32kHz audio only occasional pops when changing tracks!