How to configure a pcm to write to it periodically?

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

 



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; }





[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux