diff --git a/dacp.c b/dacp.c index 4ecc2064..c92c6f05 100644 --- a/dacp.c +++ b/dacp.c @@ -156,7 +156,7 @@ int dacp_send_command(const char *command, char **body, ssize_t *bodysize) { hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - // debug(1, "DHCP port string is \"%s:%s\".", server, portstring); + // debug(1, "DACP port string is \"%s:%s\".", server, portstring); int ires = getaddrinfo(server, portstring, &hints, &res); if (ires) { diff --git a/documents/sample dbus commands b/documents/sample dbus commands index a0306880..0a7c398d 100644 --- a/documents/sample dbus commands +++ b/documents/sample dbus commands @@ -15,4 +15,9 @@ dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/Shair # Include Elapsed Time in Log Entries dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:org.gnome.ShairportSync.Diagnostics string:ElapsedTime variant:boolean:true +# Play using regular Remote Control +dbus-send --system --print-reply --type=method_call --dest=org.gnome.ShairportSync '/org/gnome/ShairportSync' org.gnome.ShairportSync.RemoteControl.Play +#Remote Control commands include: Play, Pause, PlayPause, Resume, Stop, Next, Previous, VolumeUp, VolumeDown, ToggleMute, FastForward, Rewind, ShuffleSongs +# Set Volume using Advanced Remote Control +dbus-send --system --print-reply --type=method_call --dest=org.gnome.ShairportSync '/org/gnome/ShairportSync' org.gnome.ShairportSync.AdvancedRemoteControl.SetVolume int32:50 \ No newline at end of file diff --git a/mdns.c b/mdns.c index 855f3c3e..e45dacc5 100644 --- a/mdns.c +++ b/mdns.c @@ -106,9 +106,7 @@ void mdns_unregister(void) { void *mdns_dacp_monitor(char *dacp_id) { void *reply = NULL; - if ((dacp_id==NULL) || (*dacp_id=='\0')) - debug(1, "A null or zero-length DACP-ID string was provided for monitoring -- nothing done."); - else { + if ((dacp_id!=NULL) && (*dacp_id!='\0')) { if ((config.mdns) && (config.mdns->mdns_dacp_monitor)) { reply = config.mdns->mdns_dacp_monitor(dacp_id); if (reply == NULL) { diff --git a/mdns_avahi.c b/mdns_avahi.c index f231eecd..6756c1ea 100644 --- a/mdns_avahi.c +++ b/mdns_avahi.c @@ -448,7 +448,7 @@ void avahi_dacp_dont_monitor(void *userdata) { free((char *)(dbs)); debug(3, "DACP monitor successfully stopped"); } else { - debug(1, "DHCP Monitor is not running."); + debug(1, "DACP Monitor is not running."); } } diff --git a/metadata_hub.c b/metadata_hub.c index ff7eef46..4f3fc0f8 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -139,10 +139,18 @@ void run_metadata_watchers(void) { void metadata_hub_modify_epilog(int modified) { // always run this after changing an entry or a sequence of entries in the metadata_hub // debug(1, "unlocking metadata hub for writing"); + + // Here, we check to see if the dacp_server is transitioning between active and inactive + // If it's going off, we will release track metadata and image stuff + // If it's already off, we do nothing + // If it's transitioning to on, we will record it for use later. + int m = 0; - if (metadata_store.dacp_server_active == 0) { - // debug(1,"player_stop release track metadata and artwork"); - // + int tm = modified; + + if ((metadata_store.dacp_server_active == 0) && + (metadata_store.dacp_server_has_been_active != 0)) { + debug(1, "dacp_scanner going inactive -- release track metadata and artwork"); if (metadata_store.track_metadata) { m = 1; metadata_hub_release_track_metadata(metadata_store.track_metadata); @@ -154,10 +162,12 @@ void metadata_hub_modify_epilog(int modified) { } if (m) debug(2, "Release track metadata after dacp server goes inactive."); - modified += m; + tm += m; } + metadata_store.dacp_server_has_been_active = + metadata_store.dacp_server_active; // set the scanner_has_been_active now. pthread_rwlock_unlock(&metadata_hub_re_lock); - if (modified) { + if (tm) { run_metadata_watchers(); } } @@ -392,8 +402,7 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin track_metadata->sort_name = strndup(data, length); debug(2, "MH Sort Name set to: \"%s\"", track_metadata->sort_name); } else { - debug(1, - "No track metadata memory allocated when sort name description received!"); + debug(1, "No track metadata memory allocated when sort name description received!"); } break; case 'assa': @@ -401,8 +410,7 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin track_metadata->sort_artist = strndup(data, length); debug(2, "MH Sort Artist set to: \"%s\"", track_metadata->sort_artist); } else { - debug(1, - "No track metadata memory allocated when sort artist description received!"); + debug(1, "No track metadata memory allocated when sort artist description received!"); } break; case 'assu': @@ -410,8 +418,7 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin track_metadata->sort_album = strndup(data, length); debug(2, "MH Sort Album set to: \"%s\"", track_metadata->sort_album); } else { - debug(1, - "No track metadata memory allocated when sort album description received!"); + debug(1, "No track metadata memory allocated when sort album description received!"); } break; case 'assc': @@ -419,32 +426,31 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin track_metadata->sort_composer = strndup(data, length); debug(2, "MH Sort Composer set to: \"%s\"", track_metadata->sort_composer); } else { - debug(1, - "No track metadata memory allocated when sort composer description received!"); + debug(1, "No track metadata memory allocated when sort composer description received!"); } break; - default: - /* - { - char typestring[5]; - *(uint32_t *)typestring = htonl(type); - typestring[4] = 0; - char codestring[5]; - *(uint32_t *)codestring = htonl(code); - codestring[4] = 0; - char *payload; - if (length < 2048) - payload = strndup(data, length); - else - payload = NULL; - debug(1, "MH \"%s\" \"%s\" (%d bytes): \"%s\".", typestring, codestring, length, payload); - if (payload) - free(payload); - } - */ + default: + /* + { + char typestring[5]; + *(uint32_t *)typestring = htonl(type); + typestring[4] = 0; + char codestring[5]; + *(uint32_t *)codestring = htonl(code); + codestring[4] = 0; + char *payload; + if (length < 2048) + payload = strndup(data, length); + else + payload = NULL; + debug(1, "MH \"%s\" \"%s\" (%d bytes): \"%s\".", typestring, codestring, length, + payload); + if (payload) + free(payload); + } + */ break; - } } else if (type == 'ssnc') { switch (code) { diff --git a/metadata_hub.h b/metadata_hub.h index 29825555..8d003703 100644 --- a/metadata_hub.h +++ b/metadata_hub.h @@ -62,6 +62,10 @@ typedef struct metadata_bundle { int advanced_dacp_server_active; // true if there's a reachable DACP server with iTunes // capabilitiues // ; false otherwise + int dacp_server_has_been_active; // basically this is a delayed version of dacp_server_active, + // used detect transitions between server activity being on or off + // e.g. to reease metadata when a server goes inactive, but not if it's permanently + // inactive. enum play_status_type play_status; enum shuffle_status_type shuffle_status; enum repeat_status_type repeat_status; diff --git a/player.c b/player.c index 60bd9282..153ae227 100644 --- a/player.c +++ b/player.c @@ -510,9 +510,9 @@ void player_put_packet(seq_t seqno, uint32_t actual_timestamp, int64_t timestamp // here, we should check for missing frames if (!conn->ab_buffering) { int j; - for (j = 1; j <= 7; j++) { + for (j = 1; j <= 8; j++) { // check j times, after a short period of has elapsed, assuming 352 frames per packet - int back_step = (((250 * 44100) / 352) / 1000) * (j); // approx 250, 500 and 750 ms + int back_step = (((250 * 44100) / 352) / 1000) * (j); // approx 250 ms intervals int k; for (k = -2; k <= 2; k++) { if (back_step < @@ -1694,8 +1694,8 @@ static void *player_thread_func(void *arg) { // debug(3, "Play frame %d.", play_number); conn->play_number_after_flush++; if (inframe->timestamp == 0) { - debug(1, "Player has a supplied silent frame, (possibly frame %u).", - SUCCESSOR(conn->last_seqno_read)); + debug(1, "Player has supplied a silent frame, (possibly frame %u) for play number %d.", + SUCCESSOR(conn->last_seqno_read),play_number); conn->last_seqno_read = (SUCCESSOR(conn->last_seqno_read) & 0xffff); // manage the packet out of sequence minder config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio); diff --git a/rtp.c b/rtp.c index 57f204e6..0f8d3dcf 100644 --- a/rtp.c +++ b/rtp.c @@ -165,7 +165,7 @@ void *rtp_audio_receiver(void *arg) { (drand48() > config.diagnostic_drop_packet_fraction)) player_put_packet(seqno, actual_timestamp, timestamp, pktp, plen, conn); else - debug(3, "Dropping audio packet %u to simulate a bad connection.", seqno); + debug(2, "Dropping audio packet %u to simulate a bad connection.", seqno); continue; } if (type == 0x56 && seqno == 0) { @@ -391,7 +391,7 @@ void *rtp_control_receiver(void *arg) { debug(1, "Control Receiver -- Unknown RTP packet of type 0x%02X length %d, ignored.", packet[1], nread); } else { - debug(3, "Control Receiver -- dropping a packet to simulate a bad network."); + debug(2, "Control Receiver -- dropping a packet to simulate a bad network."); } } else { debug(1, "Control Receiver -- error receiving a packet."); @@ -469,7 +469,7 @@ void *rtp_timing_sender(void *arg) { } } else { - debug(1, "Timing Sender -- dropping an outbound timing packet to simulate a bad network."); + debug(2, "Timing Sender Thread -- dropping outgoing packet to simulate bad network."); } request_number++; @@ -526,13 +526,12 @@ void *rtp_timing_receiver(void *arg) { break; } nread = recv(conn->timing_socket, packet, sizeof(packet), 0); - arrival_time = get_absolute_time_in_fp(); - // clock_gettime(CLOCK_MONOTONIC,&att); if (nread >= 0) { if ((config.diagnostic_drop_packet_fraction == 0.0) || (drand48() > config.diagnostic_drop_packet_fraction)) { + arrival_time = get_absolute_time_in_fp(); // ssize_t plen = nread; // debug(1,"Packet Received on Timing Port."); @@ -725,7 +724,7 @@ void *rtp_timing_receiver(void *arg) { debug(1, "Timing port -- Unknown RTP packet of type 0x%02X length %d.", packet[1], nread); } } else { - debug(1, "Timing Receiver -- dropping a packet to simulate a bad network."); + debug(2, "Timing Receiver Thread -- dropping incoming packet to simulate a bad network."); } } else { debug(1, "Timing receiver -- error receiving a packet."); @@ -953,7 +952,7 @@ void clear_reference_timestamp(rtsp_conn_info *conn) { void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn) { if (conn->rtp_running) { // if (!request_sent) { - debug(2, "requesting resend of %d packets starting at %u.", count, first); + // debug(2, "requesting resend of %d packets starting at %u.", count, first); // request_sent = 1; //} @@ -974,14 +973,19 @@ void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn) { if ((conn->rtp_time_of_last_resend_request_error_fp) || ((time_of_sending_fp - conn->rtp_time_of_last_resend_request_error_fp) > resend_error_backoff_time)) { - if (sendto(conn->audio_socket, req, sizeof(req), 0, - (struct sockaddr *)&conn->rtp_client_control_socket, msgsize) == -1) { - char em[1024]; - strerror_r(errno, em, sizeof(em)); - debug(1, "Error %d using send-to to an audio socket: \"%s\". ", errno, em); - conn->rtp_time_of_last_resend_request_error_fp = time_of_sending_fp; + if ((config.diagnostic_drop_packet_fraction == 0.0) || + (drand48() > config.diagnostic_drop_packet_fraction)) { + if (sendto(conn->audio_socket, req, sizeof(req), 0, + (struct sockaddr *)&conn->rtp_client_control_socket, msgsize) == -1) { + char em[1024]; + strerror_r(errno, em, sizeof(em)); + debug(1, "Error %d using send-to to an audio socket: \"%s\". ", errno, em); + conn->rtp_time_of_last_resend_request_error_fp = time_of_sending_fp; + } else { + conn->rtp_time_of_last_resend_request_error_fp = 0; + } } else { - conn->rtp_time_of_last_resend_request_error_fp = 0; + debug(2, "Dropping resend request packet to simulate a bad network."); } } } else {