snd_pcm_sw_params_alloca(&sw_params);
RETURN_FALSE_ON_ERROR("snd_pcm_sw_params_current()", snd_pcm_sw_params_current(pcm_handle, sw_params));
RETURN_FALSE_ON_ERROR("snd_pcm_sw_params_set_start_threshold", snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, num_periods * period_size / 2));
+ RETURN_FALSE_ON_ERROR("snd_pcm_sw_params_set_tstamp_mode", snd_pcm_sw_params_set_tstamp_mode(pcm_handle, sw_params, SND_PCM_TSTAMP_ENABLE));
+ RETURN_FALSE_ON_ERROR("snd_pcm_sw_params_set_tstamp_type", snd_pcm_sw_params_set_tstamp_type(pcm_handle, sw_params, SND_PCM_TSTAMP_TYPE_MONOTONIC));
+
RETURN_FALSE_ON_ERROR("snd_pcm_sw_params()", snd_pcm_sw_params(pcm_handle, sw_params));
RETURN_FALSE_ON_ERROR("snd_pcm_nonblock()", snd_pcm_nonblock(pcm_handle, 1));
void ALSAInput::capture_thread_func()
{
+ if (!done_init) {
+ char thread_name[16];
+ snprintf(thread_name, sizeof(thread_name), "ALSA_C_%d", internal_dev_index);
+ pthread_setname_np(pthread_self(), thread_name);
+
+ done_init = true;
+ }
+
parent_pool->set_card_state(internal_dev_index, ALSAPool::Device::State::STARTING);
// If the device hasn't been opened already, we need to do so
RETURN_ON_ERROR("snd_pcm_start()", snd_pcm_start(pcm_handle));
parent_pool->set_card_state(internal_dev_index, ALSAPool::Device::State::RUNNING);
+ snd_pcm_status_t *status;
+ snd_pcm_status_alloca(&status);
while (!should_quit.should_quit()) {
int ret = snd_pcm_wait(pcm_handle, /*timeout=*/100);
if (ret == 0) continue; // Timeout.
}
RETURN_ON_ERROR("snd_pcm_wait()", ret);
- snd_pcm_sframes_t frames = snd_pcm_readi(pcm_handle, buffer.get(), buffer_frames);
+ ret = snd_pcm_status(pcm_handle, status);
+ RETURN_ON_ERROR("snd_pcm_status()", ret);
+
+ snd_pcm_sframes_t avail = snd_pcm_status_get_avail(status);
+ snd_htimestamp_t alsa_ts;
+ snd_pcm_status_get_htstamp(status, &alsa_ts);
+
+ snd_pcm_sframes_t frames = snd_pcm_readi(pcm_handle, buffer.get(), avail);
if (frames == -EPIPE) {
fprintf(stderr, "[%s] ALSA overrun\n", device.c_str());
snd_pcm_prepare(pcm_handle);
}
RETURN_ON_ERROR("snd_pcm_readi()", frames);
- const steady_clock::time_point now = steady_clock::now();
+ // NOTE: This assumes steady_clock::time_point is the same as clock_gettime(CLOCK_MONOTONIC).
+ const steady_clock::time_point ts = steady_clock::time_point(seconds(alsa_ts.tv_sec) + nanoseconds(alsa_ts.tv_nsec));
bool success;
do {
if (should_quit.should_quit()) return CaptureEndReason::REQUESTED_QUIT;
- success = audio_callback(buffer.get(), frames, audio_format, now);
+ success = audio_callback(buffer.get(), frames, audio_format, ts);
} while (!success);
}
return CaptureEndReason::REQUESTED_QUIT;