static char *name = NULL;
static int port = 0;
+static void register_service( AvahiClient *c );
+
static void egroup_callback(AvahiEntryGroup *g, AvahiEntryGroupState state,
AVAHI_GCC_UNUSED void *userdata) {
- if (state == AVAHI_ENTRY_GROUP_COLLISION)
- warn("Service name already exists on network!");
- if (state == AVAHI_ENTRY_GROUP_FAILURE)
- warn("Avahi entry group failure!");
+ switch ( state )
+ {
+ case AVAHI_ENTRY_GROUP_ESTABLISHED:
+ /* The entry group has been established successfully */
+ inform("Service '%s' successfully established.\n", name );
+ break;
+
+ case AVAHI_ENTRY_GROUP_COLLISION:
+ {
+ char *n;
+
+ /* A service name collision with a remote service
+ * happened. Let's pick a new name */
+ n = avahi_alternative_service_name( name );
+ avahi_free( name );
+ name = n;
+
+ warn( "Service name collision, renaming service to '%s'\n", name );
+
+ /* And recreate the services */
+ register_service( avahi_entry_group_get_client( g ) );
+ break;
+ }
+
+ case AVAHI_ENTRY_GROUP_FAILURE:
- die( "Entry group failure: %s\n", avahi_strerror( avahi_client_errno( avahi_entry_group_get_client( g ) ) ) );
++ warn( "Entry group failure: %s\n", avahi_strerror( avahi_client_errno( avahi_entry_group_get_client( g ) ) ) );
+ break;
+
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ debug(1, "Service '%s' group is not yet commited.\n", name );
+ break;
+
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ inform( "Service '%s' group is registering.\n", name );
+ break;
+
+ default:
+ warn( "Unhandled avahi egroup state: %d\n", state );
+ break;
+ }
}
static void register_service(AvahiClient *c) {
static void client_callback(AvahiClient *c, AvahiClientState state,
AVAHI_GCC_UNUSED void *userdata) {
switch (state) {
- case AVAHI_CLIENT_S_REGISTERING:
- if (group)
- avahi_entry_group_reset(group);
- break;
-
- case AVAHI_CLIENT_S_RUNNING:
- register_service(c);
- break;
-
- case AVAHI_CLIENT_FAILURE:
- case AVAHI_CLIENT_S_COLLISION:
- debug(1,"avahi client failure");
- break;
-
- case AVAHI_CLIENT_CONNECTING:
- break;
+ case AVAHI_CLIENT_S_REGISTERING:
+ if (group)
+ avahi_entry_group_reset(group);
+ break;
+
+ case AVAHI_CLIENT_S_RUNNING:
+ register_service(c);
+ break;
+
+ case AVAHI_CLIENT_FAILURE:
- die("avahi client failure");
++ warn("avahi client failure");
+ break;
+
+ case AVAHI_CLIENT_S_COLLISION:
+ warn( "Avahi state is AVAHI_CLIENT_S_COLLISION...needs a rename: %s\n", name );
+ break;
+
+ case AVAHI_CLIENT_CONNECTING:
+ inform( "Received AVAHI_CLIENT_CONNECTING\n" );
+ break;
+
+ default:
+ warn( "Unhandled avahi client state: %d\n", state );
+ break;
}
}
int64_t tsum_of_sync_errors, tsum_of_corrections, tsum_of_insertions_and_deletions,
tsum_of_drifts;
int64_t previous_sync_error, previous_correction;
- int64_t minimum_dac_queue_size = 1000000;
- int32_t minimum_buffer_occupancy = BUFFER_FRAMES;
- int32_t maximum_buffer_occupancy = 0;
+ int64_t minimum_dac_queue_size = INT64_MAX;
+ int32_t minimum_buffer_occupancy = INT32_MAX;
+ int32_t maximum_buffer_occupancy = INT32_MIN;
+ time_t playstart = time(NULL);
+
buffer_occupancy = 0;
int play_samples;
// if ((play_number/print_interval)%20==0)
if (config.statistics_requested) {
if (at_least_one_frame_seen) {
- if (config.output->delay)
- inform("Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f "
- "(ppm); total packets %d; missing packets %llu; late packets %llu; too late packets %llu; "
- "resend requests %llu; min DAC queue size %lli, min and max buffer occupancy "
- "%d and %d.",
- moving_average_sync_error, moving_average_correction * 1000000 / 352,
- moving_average_insertions_plus_deletions * 1000000 / 352,
- play_number, missing_packets,
- late_packets, too_late_packets, resend_requests, minimum_dac_queue_size,
- minimum_buffer_occupancy, maximum_buffer_occupancy);
- else
- inform("Synchronisation disabled. total packets %d; missing packets %llu; late packets %llu; too late packets %llu; "
- "resend requests %llu; min and max buffer occupancy "
- "%d and %d.",
- play_number, missing_packets,
- late_packets, too_late_packets, resend_requests,
- minimum_buffer_occupancy, maximum_buffer_occupancy);
+ if ((config.output->delay)) {
+ if (config.no_sync==0) {
+ inform("Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f "
- "(ppm); missing packets %llu; late packets %llu; too late packets %llu; "
++ "(ppm); total packets %d; missing packets %llu; late packets %llu; too late packets %llu; "
+ "resend requests %llu; min DAC queue size %lli, min and max buffer occupancy "
+ "%d and %d.",
+ moving_average_sync_error, moving_average_correction * 1000000 / 352,
- moving_average_insertions_plus_deletions * 1000000 / 352, missing_packets,
++ moving_average_insertions_plus_deletions * 1000000 / 352, play_number, missing_packets,
+ late_packets, too_late_packets, resend_requests, minimum_dac_queue_size,
+ minimum_buffer_occupancy, maximum_buffer_occupancy);
+ } else {
- inform("Synchronisation disabled. Sync error: %.1f (frames); missing packets %llu; late packets %llu; too late packets %llu; "
++ inform("Synchronisation disabled. Sync error: %.1f (frames); total packets %d; "
++ "missing packets %llu; late packets %llu; too late packets %llu; "
+ "resend requests %llu; min DAC queue size %lli, min and max buffer occupancy "
+ "%d and %d.",
- moving_average_sync_error, missing_packets,
++ moving_average_sync_error, play_number, missing_packets,
+ late_packets, too_late_packets, resend_requests, minimum_dac_queue_size,
+ minimum_buffer_occupancy, maximum_buffer_occupancy);
+ }
+ } else {
- inform("Synchronisation disabled. Missing packets %llu; late packets %llu; too late packets %llu; "
- "resend requests %llu; min and max buffer occupancy "
- "%d and %d.",
- missing_packets,
- late_packets, too_late_packets, resend_requests,
- minimum_buffer_occupancy, maximum_buffer_occupancy);
++ inform("Synchronisation disabled. Total packets %d; missing packets %llu; late packets %llu; too late packets %llu; "
++ "resend requests %llu; min and max buffer occupancy "
++ "%d and %d.",
++ play_number, missing_packets,
++ late_packets, too_late_packets, resend_requests,
++ minimum_buffer_occupancy, maximum_buffer_occupancy);
+ }
} else {
inform("No frames received in the last sampling interval.");
}
}
}
}
- int rawSeconds = (int) difftime( time( NULL ), playstart );
- int elapsedHours = rawSeconds / 3600;
- int elapsedMin = (rawSeconds / 60) % 60;
- int elapsedSec = rawSeconds % 60;
- inform( "Playback Stopped. Total playing time %02d:%02d:%02d\n", elapsedHours, elapsedMin, elapsedSec );
+
++ if (config.statistics_requested) {
++ int rawSeconds = (int) difftime( time( NULL ), playstart );
++ int elapsedHours = rawSeconds / 3600;
++ int elapsedMin = (rawSeconds / 60) % 60;
++ int elapsedSec = rawSeconds % 60;
++ inform( "Playback Stopped. Total playing time %02d:%02d:%02d\n", elapsedHours, elapsedMin, elapsedSec );
++ }
+
if (config.output->stop)
config.output->stop();
usleep(100000); // allow this time to (?) allow the alsa subsystem to finish cleaning up after itself. 50 ms seems too short