ALSA - Получение временных меток аудио буфера

У меня есть простая программа на C, которая воспроизводит аудио с использованием API-интерфейсов ALSA, и я хочу знать точную синхронизацию аудио-буферов.

Я пытаюсь получить метки времени из звукового драйвера, используя функциональность ALSA snd_pcm_htimestamp, которая возвращает два значения - метку времени и количество кадров.

Однако метка времени, возвращаемая из ALSA, не установлена ​​(нулевые значения). Вторая возвращаемая переменная, "число доступных кадров при получении метки времени", выглядит правильно установленной. Кто-нибудь имеет представление о том, почему метки времени, казалось бы, не установлены?

Я настраиваю метки времени для активации в моей настройке следующим образом:

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

И я проверяю, что это было установлено:

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

Затем в главном цикле программы, после того, как я кормлю ALSA образцами, используя snd_pcm_writeiЯ пытаюсь получить метку времени этого буфера следующим образом:

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

Тем не менее, хотя avail кажется установленным, ts всегда 0,000000000.

Я использую Raspberry Pi под управлением Raspbian с аудиоинтерфейсом ADA1475.

Заранее спасибо Энди

2 ответа

Изменение swparams должно быть применено к интерфейсу PCM с 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 позволяет изменять программные параметры в любое время, даже во время работы потока.

Похоже, у меня есть связанная проблема при чтении с USB-микрофона, и я создал для нее проблему: https://github.com/alsa-project/alsa-lib/issues/131.

Другие вопросы по тегам