'ALSA - Retrieving audio buffer timestamps

I have a simple C program that plays audio using the ALSA APIs and I wish to know the precise timing of the audio buffers.

I am attempting to retrieve the timestamps from the audio driver using ALSA's snd_pcm_htimestamp functionality, which returns two values - a timestamp and a frame count.

However, the timestamp returned from ALSA is unset (zero values). The second returned variable, the "number of available frames when timestamp was grabbed", looks to be set correctly. Does anyone have an idea as to why the timestamps are seemingly unset?

I am configuring timestamps to be activated in my setup like so:

err = snd_pcm_sw_params_set_tstamp_mode(pcmHandle, swparams, SND_PCM_TSTAMP_ENABLE);
if (err < 0) {
    printf("Unable to set timestamp mode: %s\n", snd_strerror(err));
    return err;
}

And I verify that it has been set:

snd_pcm_tstamp_t timestampMode;
err = snd_pcm_sw_params_get_tstamp_mode(swparams, &timestampMode);
if (timestampMode != SND_PCM_TSTAMP_ENABLE)
{
    // error ...
}

Then in the program's main while loop, after I feed ALSA with samples using snd_pcm_writei, I attempt to obtain that buffer's timestamp like so:

snd_pcm_writei(pcmHandle, samples, frameCount);

snd_htimestamp_t ts;
snd_pcm_uframes_t avail;
err = snd_pcm_htimestamp(pcmHandle, &avail, &ts);
if (err < 0)
{
    printf("Unable to get timestamp: %s\n", snd_strerror(err));
    return err;
}
printf("avail: %d\n", avail);
printf("%lld.%.9ld", (long long)ts.tv_sec, ts.tv_nsec);

However, whilst avail seems to be set, ts is always 0.000000000.

I am on a Raspberry Pi running Raspbian with an ADA1475 audio interface.

Thanks in advance, Andy



Solution 1:[1]

The change to swparams must be applied to the PCM interface with snd_pcm_sw_params().

/* Allocate a temporary swparams struct */
snd_pcm_sw_params_t *swparams;
snd_pcm_sw_params_alloca(&swparams);

/* Retrieve current SW parameters. */
snd_pcm_sw_params_current(pcmHandle, swparams);

/* Change software parameters. */
snd_pcm_sw_params_get_tstamp_mode(swparams, SND_PCM_TSTAMP_ENABLE);
snd_pcm_sw_params_set_tstamp_type(pcmHandle, swparams, SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY);

/* Apply updated software parameters to PCM interface. */
snd_pcm_sw_params(pcmHandle, swparams);  // <-- Change takes effect here.

ALSA allows software parameters to be changed at any time, even while the stream is running.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 qxsnap