Re: Buffer Underrun with Single Threaded ALSA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



For your information, I write ALSA PCM application without alsa-lib:

On Sat, Apr 24, 2021 at 07:14:03AM +0000, re.mcclue wrote:
>    Hi there,
>    I want to play sound using ALSA talking directly to the kernel. All
>    most all resources I searched for online used libasound. Needless to
>    say, finding your
>    Github [1] was a breath of
>    fresh air. Thank you for making it!
>    Specifically I want to play a pcm buffer (access=RW_INTERLEAVED,
>    format=S16_LE, channels=2).
>    I'm an ALSA novice, yet as I understand it, there is no concept of a
>    "write" or "play" cursor like in Windows Direct Sound API. You simply
>    feed data to the sound buffer and it plays it. If you don't write
>    enough data in a certain amount of time, you get a buffer underrun. As
>    a result, I'm unsure how to model my sound so that a buffer underrun
>    will not occur and it will be remain in sync with my program's state. I
>    have tried:
>     1. Only write the amount of samples produced in a single frame into
>        the sound buffer. This causes a buffer underrun.
>     2. Start off with writing 60ms of silence. This doesn't cause an
>        underrun, but now I am now 60ms out of sync. Lowering this time
>        will eventually cause a buffer underrun.
>     3. Buffer a bunch of frames worth of samples and then write them all
>        out. This will eventually cause a buffer overrun.
>    I know I could create a thread that will smartly populate the buffer,
>    but I don't want to have to deal with threads. I feel there is an
>    obvious single threaded solution I'm not thinking of.
>    Do you have any recommendations?
>    Thank you very much.

ALSA PCM substream has 'software configuration' (struct
snd_pcm_sw_params) apart from 'hardware configuration' (struct
snd_pcm_hw_params). The structure has 'start_threshold'. The default
value of 'start_threshold' is 1[1]. It means that audio data frame
transmission starts immediately after your application copies any audio
data frame to intermediate buffer in kernel space[2].

I think any arrangement to 'start_threshold' can avoid overrun at the
beginning of operation to copy audio data frame in your case. You can
fill intermediate buffer somehow before starting transmission if expanding
the value of 'start_threshold' by ioctl with SNDRV_PCM_IOCTL_SW_PARAMS,
then start transmission by ioctl with SNDRV_PCM_IOCTL_START.

In detail, please refer to the sample program.



Takashi Sakamoto

Alsa-user mailing list

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux