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.



  • This can cause stale mixer devices to appear. With mplayer and 32kHz audio only occasional pops when changing tracks!


Log in to reply
 

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