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@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@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@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