snd_pcm_status_get_htstamp(alsa_snd_pcm_status, &update_timestamp);
-/*
-// must be 1.1 or later to use snd_pcm_status_get_driver_htstamp
-#if SND_LIB_MINOR != 0
- snd_htimestamp_t driver_htstamp;
- snd_pcm_status_get_driver_htstamp(alsa_snd_pcm_status, &driver_htstamp);
- uint64_t driver_htstamp_ns = driver_htstamp.tv_sec;
- driver_htstamp_ns = driver_htstamp_ns * 1000000000;
- driver_htstamp_ns = driver_htstamp_ns + driver_htstamp.tv_nsec;
- debug(1,"driver_htstamp: %f.", driver_htstamp_ns * 0.000000001);
-#endif
-*/
+ /*
+ // must be 1.1 or later to use snd_pcm_status_get_driver_htstamp
+ #if SND_LIB_MINOR != 0
+ snd_htimestamp_t driver_htstamp;
+ snd_pcm_status_get_driver_htstamp(alsa_snd_pcm_status, &driver_htstamp);
+ uint64_t driver_htstamp_ns = driver_htstamp.tv_sec;
+ driver_htstamp_ns = driver_htstamp_ns * 1000000000;
+ driver_htstamp_ns = driver_htstamp_ns + driver_htstamp.tv_nsec;
+ debug(1,"driver_htstamp: %f.", driver_htstamp_ns * 0.000000001);
+ #endif
+ */
*state = snd_pcm_status_get_state(alsa_snd_pcm_status);
if ((*state == SND_PCM_STATE_RUNNING) || (*state == SND_PCM_STATE_DRAINING)) {
- // uint64_t update_timestamp_ns =
- // update_timestamp.tv_sec * (uint64_t)1000000000 + update_timestamp.tv_nsec;
+ // uint64_t update_timestamp_ns =
+ // update_timestamp.tv_sec * (uint64_t)1000000000 + update_timestamp.tv_nsec;
uint64_t update_timestamp_ns = update_timestamp.tv_sec;
update_timestamp_ns = update_timestamp_ns * 1000000000;
update_timestamp_ns = update_timestamp_ns + update_timestamp.tv_nsec;
-
// if the update_timestamp is zero, we take this to mean that the device doesn't report
// interrupt timings. (It could be that it's not a real hardware device.)
// so we switch to getting the delay the regular way
time_now_ns = time_now_ns * 1000000000;
time_now_ns = time_now_ns + tn.tv_nsec;
-
// see if it's stalled
if ((stall_monitor_start_time != 0) && (stall_monitor_frame_count == delay_temp)) {
if (ret == 0) {
uint64_t delta = time_now_ns - update_timestamp_ns;
-// uint64_t frames_played_since_last_interrupt =
-// ((uint64_t)config.output_rate * delta) / 1000000000;
-
- uint64_t frames_played_since_last_interrupt = config.output_rate;
- frames_played_since_last_interrupt = frames_played_since_last_interrupt * delta;
- frames_played_since_last_interrupt = frames_played_since_last_interrupt / 1000000000;
+ // uint64_t frames_played_since_last_interrupt =
+ // ((uint64_t)config.output_rate * delta) / 1000000000;
+ uint64_t frames_played_since_last_interrupt = config.output_rate;
+ frames_played_since_last_interrupt = frames_played_since_last_interrupt * delta;
+ frames_played_since_last_interrupt = frames_played_since_last_interrupt / 1000000000;
snd_pcm_sframes_t frames_played_since_last_interrupt_sized =
frames_played_since_last_interrupt;
- if ((frames_played_since_last_interrupt_sized < 0) || ((uint64_t)frames_played_since_last_interrupt_sized != frames_played_since_last_interrupt))
- debug(1,"overflow resizing frames_played_since_last_interrupt % " PRIx64 " to frames_played_since_last_interrupt %lx.", frames_played_since_last_interrupt, frames_played_since_last_interrupt_sized);
+ if ((frames_played_since_last_interrupt_sized < 0) ||
+ ((uint64_t)frames_played_since_last_interrupt_sized !=
+ frames_played_since_last_interrupt))
+ debug(1,
+ "overflow resizing frames_played_since_last_interrupt % " PRIx64
+ " to frames_played_since_last_interrupt %lx.",
+ frames_played_since_last_interrupt, frames_played_since_last_interrupt_sized);
delay_temp = delay_temp - frames_played_since_last_interrupt_sized;
}
*delay = delay_temp;
conn->packet_count_since_flush++;
conn->time_of_last_audio_packet = time_now;
if (conn->connection_state_to_output) { // if we are supposed to be processing these packets
- abuf_t *abuf = 0;
- if (!conn->ab_synced) {
- // if this is the first packet...
- debug(3, "syncing to seqno %u.", seqno);
- conn->ab_write = seqno;
- conn->ab_read = seqno;
- conn->ab_synced = 1;
- } else if (original_format == 0) {
- // if the packet is coming in original format, the sequence number is important
- // otherwise, ignore is by setting it equal to the expected sequence number in ab_write
- seqno = conn->ab_write;
- }
- if (conn->ab_write ==
- seqno) { // if this is the expected packet (which could be the first packet...)
- if (conn->input_frame_rate_starting_point_is_valid == 0) {
- if ((conn->packet_count_since_flush >= 500) && (conn->packet_count_since_flush <= 510)) {
- conn->frames_inward_measurement_start_time = time_now;
- conn->frames_inward_frames_received_at_measurement_start_time = actual_timestamp;
- conn->input_frame_rate_starting_point_is_valid = 1; // valid now
- }
- }
- conn->frames_inward_measurement_time = time_now;
- conn->frames_inward_frames_received_at_measurement_time = actual_timestamp;
- abuf = conn->audio_buffer + BUFIDX(seqno);
- conn->ab_write = seqno + 1; // move the write pointer to the next free space
- } else if (seq_order(conn->ab_write, seqno, conn->ab_read)) { // newer than expected
- int32_t gap = seq_diff(conn->ab_write, seqno, conn->ab_read);
- if (gap <= 0)
- debug(1, "Unexpected gap size: %d.", gap);
- int i;
- for (i = 0; i < gap; i++) {
- abuf = conn->audio_buffer + BUFIDX(seq_sum(conn->ab_write, i));
- abuf->ready = 0; // to be sure, to be sure
- abuf->resend_request_number = 0;
- abuf->initialisation_time =
- time_now; // this represents when the packet was noticed to be missing
- abuf->status = 1 << 0; // signifying missing
- abuf->resend_time = 0;
- abuf->given_timestamp = 0;
- abuf->sequence_number = 0;
+ abuf_t *abuf = 0;
+ if (!conn->ab_synced) {
+ // if this is the first packet...
+ debug(3, "syncing to seqno %u.", seqno);
+ conn->ab_write = seqno;
+ conn->ab_read = seqno;
+ conn->ab_synced = 1;
+ } else if (original_format == 0) {
+ // if the packet is coming in original format, the sequence number is important
+ // otherwise, ignore is by setting it equal to the expected sequence number in ab_write
+ seqno = conn->ab_write;
+ }
+ if (conn->ab_write ==
+ seqno) { // if this is the expected packet (which could be the first packet...)
+ if (conn->input_frame_rate_starting_point_is_valid == 0) {
+ if ((conn->packet_count_since_flush >= 500) && (conn->packet_count_since_flush <= 510)) {
+ conn->frames_inward_measurement_start_time = time_now;
+ conn->frames_inward_frames_received_at_measurement_start_time = actual_timestamp;
+ conn->input_frame_rate_starting_point_is_valid = 1; // valid now
}
- // debug(1,"N %d s %u.",seq_diff(ab_write,PREDECESSOR(seqno))+1,ab_write);
- abuf = conn->audio_buffer + BUFIDX(seqno);
- // rtp_request_resend(ab_write, gap);
- // resend_requests++;
- conn->ab_write = seqno + 1;
- } else if (seq_order(conn->ab_read, seqno,
- conn->ab_read)) { // older than expected but not too late
- conn->late_packets++;
- abuf = conn->audio_buffer + BUFIDX(seqno);
- } else { // too late.
- conn->too_late_packets++;
}
-
- if (abuf) {
- int datalen = conn->max_frames_per_packet;
- abuf->initialisation_time = time_now;
+ conn->frames_inward_measurement_time = time_now;
+ conn->frames_inward_frames_received_at_measurement_time = actual_timestamp;
+ abuf = conn->audio_buffer + BUFIDX(seqno);
+ conn->ab_write = seqno + 1; // move the write pointer to the next free space
+ } else if (seq_order(conn->ab_write, seqno, conn->ab_read)) { // newer than expected
+ int32_t gap = seq_diff(conn->ab_write, seqno, conn->ab_read);
+ if (gap <= 0)
+ debug(1, "Unexpected gap size: %d.", gap);
+ int i;
+ for (i = 0; i < gap; i++) {
+ abuf = conn->audio_buffer + BUFIDX(seq_sum(conn->ab_write, i));
+ abuf->ready = 0; // to be sure, to be sure
+ abuf->resend_request_number = 0;
+ abuf->initialisation_time =
+ time_now; // this represents when the packet was noticed to be missing
+ abuf->status = 1 << 0; // signifying missing
abuf->resend_time = 0;
- if ((original_format != 0) &&
- (audio_packet_decode(abuf->data, &datalen, data, len, conn) == 0)) {
- abuf->ready = 1;
- abuf->status = 0; // signifying that it was received
- abuf->length = datalen;
- abuf->given_timestamp = actual_timestamp;
- abuf->sequence_number = seqno;
- } else if (original_format == 0) {
- memcpy(abuf->data, data, len * conn->input_bytes_per_frame);
- abuf->ready = 1;
- abuf->status = 0; // signifying that it was received
- abuf->length = len;
- abuf->given_timestamp = actual_timestamp;
- abuf->sequence_number = seqno;
- } else {
- debug(1, "Bad audio packet detected and discarded.");
- abuf->ready = 0;
- abuf->status = 1 << 1; // bad packet, discarded
- abuf->resend_request_number = 0;
- abuf->given_timestamp = 0;
- abuf->sequence_number = 0;
- }
+ abuf->given_timestamp = 0;
+ abuf->sequence_number = 0;
}
+ // debug(1,"N %d s %u.",seq_diff(ab_write,PREDECESSOR(seqno))+1,ab_write);
+ abuf = conn->audio_buffer + BUFIDX(seqno);
+ // rtp_request_resend(ab_write, gap);
+ // resend_requests++;
+ conn->ab_write = seqno + 1;
+ } else if (seq_order(conn->ab_read, seqno,
+ conn->ab_read)) { // older than expected but not too late
+ conn->late_packets++;
+ abuf = conn->audio_buffer + BUFIDX(seqno);
+ } else { // too late.
+ conn->too_late_packets++;
+ }
- int rc = pthread_cond_signal(&conn->flowcontrol);
- if (rc)
- debug(1, "Error signalling flowcontrol.");
+ if (abuf) {
+ int datalen = conn->max_frames_per_packet;
+ abuf->initialisation_time = time_now;
+ abuf->resend_time = 0;
+ if ((original_format != 0) &&
+ (audio_packet_decode(abuf->data, &datalen, data, len, conn) == 0)) {
+ abuf->ready = 1;
+ abuf->status = 0; // signifying that it was received
+ abuf->length = datalen;
+ abuf->given_timestamp = actual_timestamp;
+ abuf->sequence_number = seqno;
+ } else if (original_format == 0) {
+ memcpy(abuf->data, data, len * conn->input_bytes_per_frame);
+ abuf->ready = 1;
+ abuf->status = 0; // signifying that it was received
+ abuf->length = len;
+ abuf->given_timestamp = actual_timestamp;
+ abuf->sequence_number = seqno;
+ } else {
+ debug(1, "Bad audio packet detected and discarded.");
+ abuf->ready = 0;
+ abuf->status = 1 << 1; // bad packet, discarded
+ abuf->resend_request_number = 0;
+ abuf->given_timestamp = 0;
+ abuf->sequence_number = 0;
+ }
+ }
+
+ int rc = pthread_cond_signal(&conn->flowcontrol);
+ if (rc)
+ debug(1, "Error signalling flowcontrol.");
- // resend checks
+ // resend checks
{
uint64_t minimum_wait_time =
(uint64_t)(config.resend_control_first_check_time * (uint64_t)1000000000);
// The desired latency, typically 88200 frames, will be calculated for in rtp.c,
// and any desired backend latency offset included in it there.
-
uint64_t should_be_time;
frame_to_local_time(conn->first_packet_timestamp, // this will go modulo 2^32
// we must enable packets to be released early enough for the
// audio buffer to be filled to the desired length
- uint32_t buffer_latency_offset = (uint32_t)(config.audio_backend_buffer_desired_length * conn->input_rate);
- frame_to_local_time(curframe->given_timestamp - buffer_latency_offset, // this will go modulo 2^32
- &time_to_play, conn);
+ uint32_t buffer_latency_offset =
+ (uint32_t)(config.audio_backend_buffer_desired_length * conn->input_rate);
+ frame_to_local_time(curframe->given_timestamp -
+ buffer_latency_offset, // this will go modulo 2^32
+ &time_to_play, conn);
if (local_time_now >= time_to_play) {
do_wait = 0;
debug(3, "player_flush");
do_flush(timestamp, conn);
#ifdef CONFIG_METADATA
-// only send a flush metadata message if the first packet has been seen -- it's a bogus message
+ // only send a flush metadata message if the first packet has been seen -- it's a bogus message
// otherwise
if (conn->first_packet_timestamp) {
debug(2, "pfls");
ast_apple_lossless,
} audio_stream_type;
-typedef enum {
- ts_ntp,
- ts_ptp
-} timing_source_type;
+typedef enum { ts_ntp, ts_ptp } timing_source_type;
typedef struct {
int encrypted;
#endif
typedef struct {
- int connection_number; // for debug ID purposes, nothing else...
+ int connection_number; // for debug ID purposes, nothing else...
timing_source_type type_of_timing; // are we using NTP or PTP?
- int resend_interval; // this is really just for debugging
- char *UserAgent; // free this on teardown
+ int resend_interval; // this is really just for debugging
+ char *UserAgent; // free this on teardown
int AirPlayVersion; // zero if not an AirPlay session. Used to help calculate latency
uint32_t latency; // the actual latency used for this play session
uint32_t minimum_latency; // set if an a=min-latency: line appears in the ANNOUNCE message; zero
// otherwise
int software_mute_enabled; // if we don't have a real mute that we can use
-
int fd;
int authorized; // set if a password is required and has been supplied
char *auth_nonce; // the session nonce, if needed
char client_ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client
uint16_t client_rtsp_port;
- char self_ip_string[INET6_ADDRSTRLEN]; // the ip string being used by this program -- it
- uint16_t self_rtsp_port; // could be one of many, so we need to know it
+ char self_ip_string[INET6_ADDRSTRLEN]; // the ip string being used by this program -- it
+ uint16_t self_rtsp_port; // could be one of many, so we need to know it
- uint32_t self_scope_id; // if it's an ipv6 connection, this will be its scope
- short connection_ip_family; // AF_INET / AF_INET6
+ uint32_t self_scope_id; // if it's an ipv6 connection, this will be its scope
+ short connection_ip_family; // AF_INET / AF_INET6
SOCKADDR rtp_client_control_socket; // a socket pointing to the control port of the client
SOCKADDR rtp_client_timing_socket; // a socket pointing to the timing port of the client
uint64_t anchor_time; // this is the time according to the clock
uint32_t anchor_rtptime;
-
#ifdef CONFIG_AIRPLAY_2
pthread_t rtp_event_thread;
pthread_t rtp_ap2_control_thread;
uint64_t last_anchor_time_of_update;
uint64_t last_anchor_clock;
-
ssize_t ap2_audio_buffer_size;
int ap2_flush_requested;
uint32_t ap2_flush_rtp_timestamp;
unsigned char *session_key; // needs to be free'd at the end
uint64_t frames_packet;
uint64_t type;
- uint64_t networkTimeTimelineID; // the clock ID used by the player
+ uint64_t networkTimeTimelineID; // the clock ID used by the player
char *ap2_timing_peer_list_message;
void player_volume_without_notification(double f, rtsp_conn_info *conn);
void player_flush(uint32_t timestamp, rtsp_conn_info *conn);
void player_full_flush(rtsp_conn_info *conn);
-void player_put_packet(int original_format, seq_t seqno, uint32_t actual_timestamp, uint8_t *data, int len,
- rtsp_conn_info *conn);
+void player_put_packet(int original_format, seq_t seqno, uint32_t actual_timestamp, uint8_t *data,
+ int len, rtsp_conn_info *conn);
int64_t monotonic_timestamp(uint32_t timestamp,
rtsp_conn_info *conn); // add an epoch to the timestamp. The monotonic
// timestamp guaranteed to start between 2^32 2^33
*raw_offset = nqptp_data.local_to_master_time_offset;
response = 0;
} else {
- debug(1,"clock not valid");
+ debug(1, "clock not valid");
response = -2; // clock info not valid
}
} else {
if (failure_message_sent == 0) {
- warn("This version of Shairport Sync requires an NQPTP with a Shared Memory Interface Version %u, but the installed version is %u. Please install the correct version of NQPTP.", NQPTP_SHM_STRUCTURES_VERSION, nqptp_data.version);
+ warn("This version of Shairport Sync requires an NQPTP with a Shared Memory Interface "
+ "Version %u, but the installed version is %u. Please install the correct version of "
+ "NQPTP.",
+ NQPTP_SHM_STRUCTURES_VERSION, nqptp_data.version);
failure_message_sent = 1;
}
}
#include <sodium.h>
#endif
-
struct Nvll {
char *name;
double value;
obfp += 2;
};
*obfp = 0;
-
-
+
+
// get raw timestamp information
// I think that a good way to understand these timestamps is that
// (1) the rtlt below is the timestamp of the frame that should be playing at the
// Thus, (3) the latency can be calculated by subtracting the second from the
// first.
// There must be more to it -- there something missing.
-
+
// In addition, it seems that if the value of the short represented by the second
// pair of bytes in the packet is 7
// then an extra time lag is expected to be added, presumably by
// the AirPort Express.
-
+
// Best guess is that this delay is 11,025 frames.
-
+
uint32_t rtlt = nctohl(&packet[4]); // raw timestamp less latency
uint32_t rt = nctohl(&packet[16]); // raw timestamp
-
+
uint32_t fl = nctohs(&packet[2]); //
-
+
debug(1,"Sync Packet of %d bytes received: \"%s\", flags: %d, timestamps %u and %u,
giving a latency of %d frames.",plen,obf,fl,rt,rtlt,rt-rtlt);
//debug(1,"Monotonic timestamps are: %" PRId64 " and %" PRId64 "
la, max_frames, conn->latency);
} else {
- // here we have the latency but it does not yet account for the audio_backend_latency_offset
- int32_t latency_offset = (uint32_t)(config.audio_backend_latency_offset * conn->input_rate);
+ // here we have the latency but it does not yet account for the
+ // audio_backend_latency_offset
+ int32_t latency_offset =
+ (uint32_t)(config.audio_backend_latency_offset * conn->input_rate);
int32_t adjusted_latency = latency_offset + (int32_t)la;
- if ((adjusted_latency < 0) || (adjusted_latency > (int32_t)(conn->max_frames_per_packet * (BUFFER_FRAMES - config.minimum_free_buffer_headroom))))
+ if ((adjusted_latency < 0) ||
+ (adjusted_latency >
+ (int32_t)(conn->max_frames_per_packet *
+ (BUFFER_FRAMES - config.minimum_free_buffer_headroom))))
warn("audio_backend_latency_offset out of range -- ignored.");
else
la = adjusted_latency;
debug(1,
"New latency: %" PRIu32 ", sync latency: %" PRIu32
", minimum latency: %" PRIu32 ", maximum "
- "latency: %" PRIu32 ", fixed offset: %" PRIu32 ", audio_backend_latency_offset: %f.",
+ "latency: %" PRIu32 ", fixed offset: %" PRIu32
+ ", audio_backend_latency_offset: %f.",
la, sync_rtp_timestamp - rtp_timestamp_less_latency, conn->minimum_latency,
- conn->maximum_latency, config.fixedLatencyOffset, config.audio_backend_latency_offset);
+ conn->maximum_latency, config.fixedLatencyOffset,
+ config.audio_backend_latency_offset);
}
}
}
conn->remote_timing_port = tport;
conn->local_control_port = bind_UDP_port(conn->connection_ip_family, conn->self_ip_string,
- conn->self_scope_id, &conn->control_socket);
+ conn->self_scope_id, &conn->control_socket);
conn->local_timing_port = bind_UDP_port(conn->connection_ip_family, conn->self_ip_string,
- conn->self_scope_id, &conn->timing_socket);
+ conn->self_scope_id, &conn->timing_socket);
conn->local_audio_port = bind_UDP_port(conn->connection_ip_family, conn->self_ip_string,
- conn->self_scope_id, &conn->audio_socket);
+ conn->self_scope_id, &conn->audio_socket);
debug(3, "listening for audio, control and timing on ports %d, %d, %d.", conn->local_audio_port,
conn->local_control_port, conn->local_timing_port);
return result;
}
-void set_ntp_anchor_info(rtsp_conn_info *conn, uint32_t rtptime,
- uint64_t networktime) {
+void set_ntp_anchor_info(rtsp_conn_info *conn, uint32_t rtptime, uint64_t networktime) {
conn->anchor_remote_info_is_valid = 1;
conn->anchor_rtptime = rtptime;
conn->anchor_time = networktime;
int32_t timestamp_interval = timestamp - conn->anchor_rtptime;
int64_t timestamp_interval_time = timestamp_interval;
timestamp_interval_time = timestamp_interval_time * time_difference;
- timestamp_interval_time = timestamp_interval_time /
- frame_difference; // this is the nominal time, based on the
- // fps specified between current and
- // previous sync frame.
- remote_time_of_timestamp = conn->anchor_time +
- timestamp_interval_time; // based on the reference timestamp time
- // plus the time interval calculated based
- // on the specified fps.
+ timestamp_interval_time =
+ timestamp_interval_time / frame_difference; // this is the nominal time, based on the
+ // fps specified between current and
+ // previous sync frame.
+ remote_time_of_timestamp =
+ conn->anchor_time + timestamp_interval_time; // based on the reference timestamp time
+ // plus the time interval calculated based
+ // on the specified fps.
*time = remote_time_of_timestamp - local_to_remote_time_difference_now(conn);
debug_mutex_unlock(&conn->reference_time_mutex, 0);
return result;
#ifdef CONFIG_AIRPLAY_2
void set_ptp_anchor_info(rtsp_conn_info *conn, uint64_t clock_id, uint32_t rtptime,
- uint64_t networktime) {
+ uint64_t networktime) {
if (conn->anchor_clock != clock_id)
debug(1, "Connection %d: Set Anchor Clock: %" PRIx64 ".", conn->connection_number, clock_id);
conn->anchor_remote_info_is_valid = 1;
}
int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
- uint64_t *anchorLocalTime) {
+ uint64_t *anchorLocalTime) {
int response = 0;
uint64_t actual_clock_id, actual_offset;
// this is now only used for calculating when to ask for resends
conn->latency = notified_latency + 11035 + added_latency;
// debug(1,"conn->latency is %d.", conn->latency);
- set_ptp_anchor_info(conn, clock_id, frame_1 - 11035 - added_latency, remote_packet_time_ns);
+ set_ptp_anchor_info(conn, clock_id, frame_1 - 11035 - added_latency,
+ remote_packet_time_ns);
} break;
case 0xd6:
return local_ptp_time_to_frame(time, frame, conn);
}
-void reset_anchor_info(rtsp_conn_info *conn) {
- reset_ptp_anchor_info(conn);
-}
+void reset_anchor_info(rtsp_conn_info *conn) { reset_ptp_anchor_info(conn); }
int have_timestamp_timing_information(rtsp_conn_info *conn) {
return have_ptp_timing_information(conn);
return local_ntp_time_to_frame(time, frame, conn);
}
-void reset_anchor_info(rtsp_conn_info *conn) {
- reset_ntp_anchor_info(conn);
-}
+void reset_anchor_info(rtsp_conn_info *conn) { reset_ntp_anchor_info(conn); }
int have_timestamp_timing_information(rtsp_conn_info *conn) {
return have_ntp_timestamp_timing_information(conn);
}
#endif
-
-
void *rtp_ap2_timing_receiver(void *arg);
void *rtp_ap2_general_message_timing_receiver(void *arg);
void set_ptp_anchor_info(rtsp_conn_info *conn, uint64_t clock_id, uint32_t rtptime,
- uint64_t networktime);
+ uint64_t networktime);
#endif
#endif // _RTP_H
int32_t added_latency = (int32_t)(config.audio_backend_latency_offset * conn->input_rate);
set_ptp_anchor_info(conn, conn->networkTimeTimelineID, anchorRTPTime - added_latency,
- anchorTimeNanoseconds);
+ anchorTimeNanoseconds);
}
item = plist_dict_get_item(messagePlist, "rate");
debug(3, "Connection %d: Checking play lock.", conn->connection_number);
release_play_lock(conn);
- #ifdef CONFIG_AIRPLAY_2
+#ifdef CONFIG_AIRPLAY_2
if (conn->server_setup_ctx)
free(conn->server_setup_ctx);
- #endif
+#endif
debug(1, "Connection %d: terminated.", conn->connection_number);
conn->running = 0;
#endif
*/
#ifdef CONFIG_DBUS_INTERFACE
- debug(2, "Stopping D-Bus service");
- stop_dbus_service();
+ debug(2, "Stopping D-Bus service");
+ stop_dbus_service();
#endif
- if (g_main_loop) {
- debug(2, "Stopping D-Bus Loop Thread");
- g_main_loop_quit(g_main_loop);
- pthread_join(dbus_thread, NULL);
- }
+ if (g_main_loop) {
+ debug(2, "Stopping D-Bus Loop Thread");
+ g_main_loop_quit(g_main_loop);
+ pthread_join(dbus_thread, NULL);
+ }
#endif
#ifdef CONFIG_DACP_CLIENT
#endif
#ifdef CONFIG_METADATA
- debug(2, "Stopping metadata");
- metadata_stop(); // close down the metadata pipe
+ debug(2, "Stopping metadata");
+ metadata_stop(); // close down the metadata pipe
#endif
- debug(2, "Deinitialising the audio backend.");
- activity_monitor_stop(0);
+ debug(2, "Deinitialising the audio backend.");
+ activity_monitor_stop(0);
activity_monitor_stop(0);
}
#ifdef CONFIG_SOXR
- // be careful -- not sure if the thread can be cancelled cleanly, so wait for it to shut down
- debug(2, "Waiting for SoXr timecheck to terminate...");
- pthread_join(soxr_time_check_thread, NULL);
+ // be careful -- not sure if the thread can be cancelled cleanly, so wait for it to shut down
+ debug(2, "Waiting for SoXr timecheck to terminate...");
+ pthread_join(soxr_time_check_thread, NULL);
#endif
if (conns)