in audio_jack.c, return the delay in terms of frames at Shairport Sync's output rate, not the Jack Audio server's internal rate.

This commit is contained in:
Mike Brady
2024-10-31 13:03:23 +00:00
parent 616b6e71fd
commit b221e1322d
+15 -9
View File
@@ -1,6 +1,6 @@
/*
* jack output driver. This file is part of Shairport Sync.
* Copyright (c) 2019 -- 2022 Mike Brady <4265913+mikebrady@users.noreply.github.com>,
* Copyright (c) 2019 -- 2024 Mike Brady <4265913+mikebrady@users.noreply.github.com>,
* Jörn Nettingsmeier <nettings@luchtbeweging.nl>
*
* All rights reserved.
@@ -50,8 +50,11 @@ pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;
jack_port_t *port[NPORTS];
const char *port_name[NPORTS] = {"out_L", "out_R"};
int sps_sample_rate;
jack_client_t *client;
jack_nframes_t sample_rate;
jack_nframes_t jack_sample_rate;
jack_nframes_t jack_latency;
jack_ringbuffer_t *jackbuf;
@@ -235,17 +238,17 @@ static int jack_init(__attribute__((unused)) int argc, __attribute__((unused)) c
if (!client) {
die("Could not start JACK server. JackStatus is %x", status);
}
sample_rate = jack_get_sample_rate(client);
jack_sample_rate = jack_get_sample_rate(client);
#ifdef CONFIG_SOXR
if (config.jack_soxr_resample_quality >= SOXR_QQ) {
quality_spec = soxr_quality_spec(config.jack_soxr_resample_quality, 0);
io_spec = soxr_io_spec(SOXR_INT16_I, SOXR_FLOAT32_I);
} else
#endif
if (sample_rate != 44100) {
if (jack_sample_rate != 44100) {
die("The JACK server is running at the wrong sample rate (%d) for Shairport Sync."
" Must be 44100 Hz.",
sample_rate);
jack_sample_rate);
}
jack_set_process_callback(client, &process, NULL);
jack_set_graph_order_callback(client, &graph, NULL);
@@ -329,6 +332,7 @@ static void jack_start(int i_sample_rate, __attribute__((unused)) int i_sample_f
// Nothing to do, JACK client has already been set up at jack_init().
// Also, we have no say over the sample rate or sample format of JACK,
// We convert the 16bit samples to float, and die if the sample rate is != 44k1 without soxr.
sps_sample_rate = i_sample_rate;
#ifdef CONFIG_SOXR
if (config.jack_soxr_resample_quality >= SOXR_QQ) {
// we might improve a bit with soxr_clear if the sample_rate doesn't change
@@ -336,7 +340,7 @@ static void jack_start(int i_sample_rate, __attribute__((unused)) int i_sample_f
soxr_delete(soxr);
}
soxr_error_t e = NULL;
soxr = soxr_create(i_sample_rate, sample_rate, NPORTS, &e, &io_spec, &quality_spec, NULL);
soxr = soxr_create(sps_sample_rate, jack_sample_rate, NPORTS, &e, &io_spec, &quality_spec, NULL);
if (!soxr) {
die("Unable to create soxr resampler for JACK: %s", e);
}
@@ -366,13 +370,15 @@ static int jack_delay(long *the_delay) {
debug(2, "audio_occupancy_now is %d.", audio_occupancy_now);
pthread_mutex_unlock(&buffer_mutex);
int64_t frames_processed_since_latest_latency_check = (delta * sample_rate) / 1000000000;
int64_t frames_processed_since_latest_latency_check = (delta * jack_sample_rate) / 1000000000;
// debug(1,"delta: %" PRId64 " frames.",frames_processed_since_latest_latency_check);
// jack_latency is set by the graph() callback, it's the average of the maximum
// latencies of all our output ports. Adjust this constant baseline delay according
// to the buffer fill level:
*the_delay = jack_latency + audio_occupancy_now - frames_processed_since_latest_latency_check;
// debug(1,"reporting a delay of %d frames",*the_delay);
int64_t the_delay_in_jack_frames = jack_latency + audio_occupancy_now - frames_processed_since_latest_latency_check;
int64_t the_delay_in_sps_frames = (the_delay_in_jack_frames * sps_sample_rate) / jack_sample_rate;
*the_delay = the_delay_in_sps_frames;
// debug(2, "reporting a delay of %ld frames at Shairport Sync's rate of %d FPS.",*the_delay, sps_sample_rate);
return 0;
}