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 0

    Mb 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.


Log in to reply
 

Looks like your connection to Community was lost, please wait while we try to reconnect.