PS: Seems the formatting for my example broke. Here's a paste: https://paste.debian.net/1304802/ Am Sonntag, dem 21.01.2024 um 11:47 +0000 schrieb Philipp Stanner: > Hi all, > > hope this is the right list. [1] stated that it's also intended for > "application developers", so I ask here. > > I've got a program that uses timers to periodically read samples from > a > microphone and write to a sound device. > The timer's period is, for example, 20ms. > So I have a sample rate of r = 16000, frame sizes of 20ms, a bit > depth > of 16 and therefore 320 samples per 20ms. > I try to write those 320 samples timer-controled every 20ms to the > pcm > device. > > > That works fine when reading samples. > When writing, however, it seems that snd_pcm_writei() blocks longer > than the 20ms. Which it shouldn't do, as far as I understand > snd_pcm_set_params() delay-parameter. > I'll attach the example below. > > So, I'd have a number of questions: > 1. Am I even using ALSA as it's intended? As far as I saw in the > API, there's the possiblity to get poll()able file descriptors > from the API. So should I, instead of using my own timers, > configure the ALSA interface to become readable every 20ms? > 2. Why does my example not work as I intended? What does the > "latency" parameter in snd_pcm_set_params() actually do? > 3. Is the 'size' parameter in the write functions [2] the size in > bytes or in samples? So if I configured SND_PCM_S16_LE and pass > size = 10, will it read 10 bytes or 160 bit? It seems to be > that > it's the number of samples, whose type has been set with > snd_pcm_set_params(). The docu isn't super clear to me, though. > > It seems that the size parameter has changed a bit. > At least the examples here [3] are faulting when I build them with > -fsanitize=address > > Thx a lot! > Philipp > > > [1] https://www.alsa-project.org/wiki/Mailing-lists > [2] > https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#gabc748a500743713eafa960c7d104ca6f > [3] http://equalarea.com/paul/alsa-audio.html > > > Example: > /* > * This is a mini-example of the code I took for my draft ofa > broader application. > * The main difference is that I call snd_pcm_writei() when my timer > fires. > */ > #include <alsa/asoundlib.h> static char *device = "default"; /* > playback device */ unsigned char buffer[16*1024]; /* some random data > */ int main(void) { int err; unsigned int i; snd_pcm_t *handle; > snd_pcm_sframes_t frames; for (i = 0; i < sizeof(buffer); i++) > buffer[i] = random() & 0xff; if ((err = snd_pcm_open(&handle, device, > SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("Playback open error: > %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } if ((err = > snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, > SND_PCM_ACCESS_RW_INTERLEAVED, 1, 16000, 1, 20000)) < 0) { > printf("Playback open error: %s\n", snd_strerror(err)); > exit(EXIT_FAILURE); } for (i = 0; i < 16; i++) { frames = > snd_pcm_writei(handle, buffer, sizeof(buffer) / sizeof(short)); if > (frames < 0) frames = snd_pcm_recover(handle, frames, 0); if (frames > < 0) { printf("snd_pcm_writei failed: %s\n", snd_strerror(frames)); > break; } if (frames > 0 && frames < (long)(sizeof(buffer) / > sizeof(short))) printf("Short write (expected %li, wrote %li)\n", > (long)(sizeof(buffer) / sizeof(short)), frames); } /* pass the > remaining samples, otherwise they're dropped in close */ err = > snd_pcm_drain(handle); if (err < 0) printf("snd_pcm_drain failed: > %s\n", snd_strerror(err)); snd_pcm_close(handle); return 0; } >