]> git.sesse.net Git - nageru/blobdiff - nageru/alsa_input.cpp
Fix a Clang 19 warning.
[nageru] / nageru / alsa_input.cpp
index ae2e7ffbdee3ce4e62c6578f1a59346a9c8b40cb..f26a012d9836b250524fee8230e6beb7e1287339 100644 (file)
@@ -1,15 +1,18 @@
 #include "alsa_input.h"
 
 #include <alsa/error.h>
+#include <alsa/global.h>
+#include <alsa/pcm.h>
 #include <assert.h>
+#include <chrono>
 #include <errno.h>
+#include <pthread.h>
 #include <stdio.h>
-#include <unistd.h>
+#include <thread>
 #include <cstdint>
 
 #include "alsa_pool.h"
 #include "bmusb/bmusb.h"
-#include "shared/timebase.h"
 
 using namespace std;
 using namespace std::chrono;
@@ -111,6 +114,9 @@ bool ALSAInput::open_device()
        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));
@@ -171,6 +177,14 @@ void ALSAInput::stop_capture_thread()
 
 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
@@ -221,7 +235,8 @@ ALSAInput::CaptureEndReason ALSAInput::do_capture()
        RETURN_ON_ERROR("snd_pcm_start()", snd_pcm_start(pcm_handle));
        parent_pool->set_card_state(internal_dev_index, ALSAPool::Device::State::RUNNING);
 
-       uint64_t num_frames_output = 0;
+       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.
@@ -233,7 +248,14 @@ ALSAInput::CaptureEndReason ALSAInput::do_capture()
                }
                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);
@@ -246,13 +268,13 @@ ALSAInput::CaptureEndReason ALSAInput::do_capture()
                }
                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);
-               num_frames_output += frames;
        }
        return CaptureEndReason::REQUESTED_QUIT;
 }