Broken Pipe with SNDRV_PCM_IOCTL_WRITEI_FRAMES

Ryan McClue re.mcclue at protonmail.com
Mon Sep 27 11:48:38 CEST 2021


Hi Philippe,
My reason for using ioctl()'s is to better understand how ALSA works. I'm very close to achieving my goal of playing pcm with ioctl()'s. I want to make the code public so everyone can gain better knowledge of linux sound.
In regards to using alsa-lib, I can equate my example to snd_pcm_writei() and snd_pcm_prepare()
As I understand it, the EPIPE indicates a buffer underrun. However, I'm recovering with prepare.
Why would there be total silence?
--
Ryan McClue, Sydney

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Monday, September 27th, 2021 at 7:21 PM, Philippe Bekaert <linux at panokkel.be> wrote:

> Hi Ryan,
>
> I realize this is probably not the answer you are waiting and hoping for, but why do you use the ioctl interface directly in the first place?
> People on this list will likely be more alarmed if you had problems with audio I/O, when done as explained on
> https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html
> and illustrated in the examples.
>
> Best,
>
> Philippe.
>
>> On 27 Sep 2021, at 01:21, Ryan McClue <re.mcclue at protonmail.com> wrote:
>>
>> I've update my loop to:
>>
>> struct
>>
>> snd_xferi
>>
>> transfer
>>
>> =
>>
>> {};
>> transfer.buf = (u8 *)buffer;
>> transfer.frames = num_base_samples;
>>
>> int
>>
>> res = ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &transfer);
>>
>> if
>>
>> (res == -EPIPE) {
>> ioctl(fd, SNDRV_PCM_IOCTL_PREPARE);
>>
>> This removes the Broken Pipe, however no sound is heard.
>> --
>> Ryan McClue, Sydney
>>
>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
>> On Sunday, September 26th, 2021 at 7:01 PM, Ryan McClue <re.mcclue at protonmail.com> wrote:
>>
>>> Hello again.
>>> I'm using alsa-kernel.
>>> My configuration:
>>> SNDRV_PCM_HW_PARAM_ACCESS = SNDRV_PCM_ACCESS_RW_INTERLEAVED
>>> SNDRV_PCM_HW_PARAM_FORMAT = SNDRV_PCM_FORMAT_S16_LE
>>> SNDRV_PCM_HW_PARAM_SUBFORMAT = SNDRV_PCM_SUBFORMAT_STD
>>> SNDRV_PCM_HW_PARAM_CHANNELS = 2
>>> SNDRV_PCM_HW_PARAM_RATE = 48000
>>>
>>> I have a vsynced game loop that is running at 60fps:
>>>
>>>> int num_base_samples = 48000 * (1 / 60);
>>>> int num_samples = num_base_samples * 2;
>>>> int16_t buffer[num_samples] = {};
>>>>
>>>> while (true) {
>>>> int16_t *samples = buffer;
>>>> for (int sample_i = 0; sample_i < num_base_samples; sample_i++) {
>>>> *samples++ = 0x33;
>>>> *samples++ = 0x33;
>>>> }
>>>>
>>>> struct snd_xferi transfer = {};
>>>> transfer.buf = buffer;
>>>> transfer.frames = num_base_samples;
>>>> ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &transfer);
>>>>
>>>> // ioctl(fd, SNDRV_PCM_IOCTL_DRAIN); --> NECESSARY???
>>>> // ioctl(fd, SNDRV_PCM_IOCTL_PREPARE); --> NECESSARY???
>>>> }
>>>
>>> On the first iteration of SNDRV_PCM_IOCTL_WRITEI_FRAMES I get no error.
>>> All subsequent iterations, I get Broken Pipe error.
>>> So, to counteract this at the end of each frame I call SNDRV_PCM_IOCTL_DRAIN and SNDRV_PCM_IOCTL_PREPARE.
>>> This removes the Broken Pipe error however slows the program down by half and no sound is heard.
>>> How best to solve this issue?
>>>
>>> Thanks again
>>> --
>>> Ryan McClue, Sydney


More information about the Alsa-devel mailing list