Skip to content

Commit

Permalink
in audio_jack.c, return the delay in terms of frames at Shairport Syn…
Browse files Browse the repository at this point in the history
…c's output rate, not the Jack Audio server's internal rate.
  • Loading branch information
mikebrady committed Oct 31, 2024
1 parent 616b6e7 commit b221e13
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions audio_jack.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* jack output driver. This file is part of Shairport Sync.
* Copyright (c) 2019 -- 2022 Mike Brady <[email protected]>,
* Copyright (c) 2019 -- 2024 Mike Brady <[email protected]>,
* Jörn Nettingsmeier <[email protected]>
*
* All rights reserved.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -329,14 +332,15 @@ 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
if (soxr) {
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);
}
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit b221e13

Please sign in to comment.