Re: How to configure a pcm to write to it periodically?

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

 



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





[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