/*
* Activity Monitor
- *
+ *
* Contains code to run an activity flag and associated timer
- * A pthread implements a simple state machine with three states,
+ * A pthread implements a simple state machine with three states,
* "idle", "active" and "timing out".
- *
- *
+ *
+ *
* This file is part of Shairport Sync.
* Copyright (c) Mike Brady 2019
* All rights reserved.
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <stdlib.h>
#include <errno.h>
#include <inttypes.h>
+#include <stdlib.h>
#include <sys/types.h>
#include "config.h"
+#include "activity_monitor.h"
#include "common.h"
#include "rtsp.h"
-#include "activity_monitor.h"
-enum am_state {am_inactive, am_active, am_timing_out} state;
-enum ps_state {ps_inactive, ps_active} player_state;
+enum am_state { am_inactive, am_active, am_timing_out } state;
+enum ps_state { ps_inactive, ps_active } player_state;
pthread_t activity_monitor_thread;
pthread_mutex_t activity_monitor_mutex;
pthread_cond_t activity_monitor_cv;
void going_active(int block) {
- // debug(1, "activity_monitor: state transitioning to \"active\" with%s blocking", block ? "" : "out");
+ // debug(1, "activity_monitor: state transitioning to \"active\" with%s blocking", block ? "" :
+ // "out");
if (config.cmd_active_start)
command_execute(config.cmd_active_start, "", block);
#ifdef CONFIG_METADATA
- debug(2, "abeg"); // active mode begin
- send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points
+ debug(2, "abeg"); // active mode begin
+ send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points
#endif
}
void going_inactive(int block) {
- // debug(1, "activity_monitor: state transitioning to \"inactive\" with%s blocking", block ? "" : "out");
+ // debug(1, "activity_monitor: state transitioning to \"inactive\" with%s blocking", block ? "" :
+ // "out");
if (config.cmd_active_stop)
command_execute(config.cmd_active_stop, "", block);
#ifdef CONFIG_METADATA
- debug(2, "aend"); // active mode end
- send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points
+ debug(2, "aend"); // active mode end
+ send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points
#endif
}
// The reason for all this is that we might want to perform the attached scripts
// and wait for them to complete before continuing. If they were perfomed in the
// activity monitor thread, then we coldn't wait for them to complete.
-
+
// Thus, the only time the thread will execute a going_... function is when a non-zero
// timeout actually matures.
-
+
if ((state == am_inactive) && (player_state == ps_active)) {
- going_active(config.cmd_blocking); // note -- will be executed with the mutex locked, but that's okay
- } else if ((state == am_active) && (player_state == ps_inactive) && (config.active_mode_timeout == 0.0)) {
- going_inactive(config.cmd_blocking); // note -- will be executed with the mutex locked, but that's okay
+ going_active(
+ config.cmd_blocking); // note -- will be executed with the mutex locked, but that's okay
+ } else if ((state == am_active) && (player_state == ps_inactive) &&
+ (config.active_mode_timeout == 0.0)) {
+ going_inactive(
+ config.cmd_blocking); // note -- will be executed with the mutex locked, but that's okay
}
-
- pthread_cond_signal(&activity_monitor_cv);
+
+ pthread_cond_signal(&activity_monitor_cv);
pthread_mutex_unlock(&activity_monitor_mutex);
}
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); // can't do this in OS X, and don't need it.
rc = pthread_cond_init(&activity_monitor_cv, &attr);
pthread_condattr_destroy(&attr);
-
+
#endif
#ifdef COMPILE_FOR_OSX
rc = pthread_cond_init(&activity_monitor_cv, NULL);
if (rc)
die("activity_monitor: error %d initialising activity_monitor_cv.");
pthread_cleanup_push(activity_thread_cleanup_handler, arg);
-
+
uint64_t sec;
uint64_t nsec;
int rc;
struct timespec time_for_wait;
-
+
state = am_inactive;
player_state = ps_inactive;
-
+
pthread_mutex_lock(&activity_monitor_mutex);
do {
switch (state) {
- case am_inactive:
- // debug(1,"am_state: am_inactive");
- while (player_state != ps_active)
- pthread_cond_wait(&activity_monitor_cv, &activity_monitor_mutex);
- state = am_active;
- // going_active(); // this is done in activity_monitor_signify_activity
+ case am_inactive:
+ // debug(1,"am_state: am_inactive");
+ while (player_state != ps_active)
+ pthread_cond_wait(&activity_monitor_cv, &activity_monitor_mutex);
+ state = am_active;
+ // going_active(); // this is done in activity_monitor_signify_activity
break;
- case am_active:
- // debug(1,"am_state: am_active");
- while (player_state != ps_inactive)
- pthread_cond_wait(&activity_monitor_cv, &activity_monitor_mutex);
- if (config.active_mode_timeout == 0.0) {
- state = am_inactive;
- // going_inactive(); // this is done in activity_monitor_signify_activity
- } else {
- state = am_timing_out;
-
- uint64_t time_to_wait_for_wakeup_fp = (uint64_t)(config.active_mode_timeout *1000000); // resolution of microseconds
- time_to_wait_for_wakeup_fp = time_to_wait_for_wakeup_fp << 32;
- time_to_wait_for_wakeup_fp = time_to_wait_for_wakeup_fp / 1000000;
-
+ case am_active:
+ // debug(1,"am_state: am_active");
+ while (player_state != ps_inactive)
+ pthread_cond_wait(&activity_monitor_cv, &activity_monitor_mutex);
+ if (config.active_mode_timeout == 0.0) {
+ state = am_inactive;
+ // going_inactive(); // this is done in activity_monitor_signify_activity
+ } else {
+ state = am_timing_out;
+
+ uint64_t time_to_wait_for_wakeup_fp =
+ (uint64_t)(config.active_mode_timeout * 1000000); // resolution of microseconds
+ time_to_wait_for_wakeup_fp = time_to_wait_for_wakeup_fp << 32;
+ time_to_wait_for_wakeup_fp = time_to_wait_for_wakeup_fp / 1000000;
+
#ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN_AND_OPENBSD
- uint64_t time_of_wakeup_fp = get_absolute_time_in_fp() + time_to_wait_for_wakeup_fp;
- sec = time_of_wakeup_fp >> 32;
- nsec = ((time_of_wakeup_fp & 0xffffffff) * 1000000000) >> 32;
- time_for_wait.tv_sec = sec;
- time_for_wait.tv_nsec = nsec;
+ uint64_t time_of_wakeup_fp = get_absolute_time_in_fp() + time_to_wait_for_wakeup_fp;
+ sec = time_of_wakeup_fp >> 32;
+ nsec = ((time_of_wakeup_fp & 0xffffffff) * 1000000000) >> 32;
+ time_for_wait.tv_sec = sec;
+ time_for_wait.tv_nsec = nsec;
#endif
#ifdef COMPILE_FOR_OSX
- sec = time_to_wait_for_wakeup_fp >> 32;
- nsec = ((time_to_wait_for_wakeup_fp & 0xffffffff) * 1000000000) >> 32;
- time_for_wait.tv_sec = sec;
- time_for_wait.tv_nsec = nsec;
+ sec = time_to_wait_for_wakeup_fp >> 32;
+ nsec = ((time_to_wait_for_wakeup_fp & 0xffffffff) * 1000000000) >> 32;
+ time_for_wait.tv_sec = sec;
+ time_for_wait.tv_nsec = nsec;
#endif
- }
+ }
break;
- case am_timing_out:
- // debug(1,"am_state: am_timing_out");
- rc = 0;
- while ((player_state != ps_active) && (rc != ETIMEDOUT)) {
+ case am_timing_out:
+ // debug(1,"am_state: am_timing_out");
+ rc = 0;
+ while ((player_state != ps_active) && (rc != ETIMEDOUT)) {
#ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN_AND_OPENBSD
- rc = pthread_cond_timedwait(&activity_monitor_cv, &activity_monitor_mutex, &time_for_wait); // this is a pthread cancellation point
+ rc = pthread_cond_timedwait(&activity_monitor_cv, &activity_monitor_mutex,
+ &time_for_wait); // this is a pthread cancellation point
#endif
#ifdef COMPILE_FOR_OSX
- rc = pthread_cond_timedwait_relative_np(&activity_monitor_cv, &activity_monitor_mutex, &time_for_wait);
+ rc = pthread_cond_timedwait_relative_np(&activity_monitor_cv, &activity_monitor_mutex,
+ &time_for_wait);
#endif
- }
- if (player_state == ps_active)
- state = am_active; // player has gone active -- do nothing, because it's still active
- else if (rc == ETIMEDOUT) {
- state = am_inactive;
- pthread_mutex_unlock(&activity_monitor_mutex);
- going_inactive(0); // don't wait for completion -- it makes no sense
- pthread_mutex_lock(&activity_monitor_mutex);
- } else {
- // activity monitor was woken up in the state am_timing_out, but not by a timeout and player is not in ps_active state
- debug(1, "activity monitor was woken up in the state am_timing_out, but didn't change state");
- }
- break;
- default:
- debug(1,"activity monitor in an illegal state!");
+ }
+ if (player_state == ps_active)
+ state = am_active; // player has gone active -- do nothing, because it's still active
+ else if (rc == ETIMEDOUT) {
state = am_inactive;
+ pthread_mutex_unlock(&activity_monitor_mutex);
+ going_inactive(0); // don't wait for completion -- it makes no sense
+ pthread_mutex_lock(&activity_monitor_mutex);
+ } else {
+ // activity monitor was woken up in the state am_timing_out, but not by a timeout and player
+ // is not in ps_active state
+ debug(1,
+ "activity monitor was woken up in the state am_timing_out, but didn't change state");
+ }
+ break;
+ default:
+ debug(1, "activity monitor in an illegal state!");
+ state = am_inactive;
break;
}
} while (1);
- pthread_mutex_unlock(&activity_monitor_mutex);
+ pthread_mutex_unlock(&activity_monitor_mutex);
pthread_cleanup_pop(0); // should never happen
pthread_exit(NULL);
}
}
void activity_monitor_stop() {
- debug(1,"activity_monitor_stop start...");
+ debug(1, "activity_monitor_stop start...");
pthread_cancel(activity_monitor_thread);
- pthread_join(activity_monitor_thread,NULL);
- debug(1,"activity_monitor_stop complete");
+ pthread_join(activity_monitor_thread, NULL);
+ debug(1, "activity_monitor_stop complete");
}
-
void (*start)(int sample_rate, int sample_format);
// block of samples
- int (*preflight)(void *buf, int samples); // say you are about to send these samples (before interpolation)
+ int (*preflight)(void *buf,
+ int samples); // say you are about to send these samples (before interpolation)
int (*play)(void *buf, int samples);
void (*stop)(void);
buffer_size);
}
*/
- debug(1, "The alsa buffer is smaller (%lu bytes) than the desired backend buffer "
- "length (%ld) you have chosen.",
+ debug(1,
+ "The alsa buffer is smaller (%lu bytes) than the desired backend buffer "
+ "length (%ld) you have chosen.",
actual_buffer_length, config.audio_backend_buffer_desired_length);
}
config.audio_backend_buffer_interpolation_threshold_in_seconds =
0.120; // below this, basic interpolation will be used to save time.
config.alsa_maximum_stall_time = 0.200; // 200 milliseconds -- if it takes longer, it's a problem
- config.audio_backend_silence_threshold = 0.040; //start sending silent frames if the delay goes below this time
- config.audio_backend_silence_scan_interval = 0.004; //check silence threshold this often
+ config.audio_backend_silence_threshold =
+ 0.040; // start sending silent frames if the delay goes below this time
+ config.audio_backend_silence_scan_interval = 0.004; // check silence threshold this often
stall_monitor_error_threshold =
(uint64_t)1000000 * config.alsa_maximum_stall_time; // stall time max to microseconds;
stall_monitor_error_threshold = (stall_monitor_error_threshold << 32) / 1000000; // now in fp form
- debug(1, "stall_monitor_error_threshold is 0x%" PRIx64 ", with alsa_maximum_stall_time of %f sec.",
+ debug(1,
+ "stall_monitor_error_threshold is 0x%" PRIx64 ", with alsa_maximum_stall_time of %f sec.",
stall_monitor_error_threshold, config.alsa_maximum_stall_time);
stall_monitor_start_time = 0;
if (((update_timestamp_ns - stall_monitor_start_time) > stall_monitor_error_threshold) ||
((time_now_ns - stall_monitor_start_time) > stall_monitor_error_threshold)) {
- debug(2, "DAC seems to have stalled with time_now_ns: %" PRIX64
- ", update_timestamp_ns: %" PRIX64 ", stall_monitor_start_time %" PRIX64
- ", stall_monitor_error_threshold %" PRIX64 ".",
+ debug(2,
+ "DAC seems to have stalled with time_now_ns: %" PRIX64
+ ", update_timestamp_ns: %" PRIX64 ", stall_monitor_start_time %" PRIX64
+ ", stall_monitor_error_threshold %" PRIX64 ".",
time_now_ns, update_timestamp_ns, stall_monitor_start_time,
stall_monitor_error_threshold);
ret = sps_extra_code_output_stalled;
int preflight(__attribute__((unused)) void *buf, __attribute__((unused)) int samples) {
uint64_t time_now =
get_absolute_time_in_fp(); // this is to regulate access by the silence filler thread
- uint64_t standoff_time = 60; // milliseconds
- standoff_time = (standoff_time << 32)/1000;
+ uint64_t standoff_time = 60; // milliseconds
+ standoff_time = (standoff_time << 32) / 1000;
most_recent_write_time = time_now + standoff_time;
return 0;
}
int sleep_time_ms = (int)(config.audio_backend_silence_scan_interval * 1000);
long buffer_size_threshold = (long)(config.audio_backend_silence_threshold * desired_sample_rate);
-
+
uint64_t sleep_time_in_fp = sleep_time_ms;
sleep_time_in_fp = sleep_time_in_fp << 32;
sleep_time_in_fp = sleep_time_in_fp / 1000;
if ((most_recent_write_time == 0) || (present_time > most_recent_write_time)) {
-// ((present_time > most_recent_write_time) &&
-// ((present_time - most_recent_write_time) > (sleep_time_in_fp)))) {
+ // ((present_time > most_recent_write_time) &&
+ // ((present_time - most_recent_write_time) > (sleep_time_in_fp)))) {
reply = delay(&buffer_size);
if (reply != 0) {
buffer_size = 0;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <string.h>
#include <unistd.h>
#include <jack/jack.h>
* we should try. */
if (config_lookup_int(config.cfg, "jack.auto_client_open_interval", &value)) {
if ((value < 0) || (value > 300))
- debug(1, "Invalid jack auto_client_open_interval \"%sd\". It should be between 0 and 300, "
- "default is %d.",
+ debug(1,
+ "Invalid jack auto_client_open_interval \"%sd\". It should be between 0 and 300, "
+ "default is %d.",
value, config.jack_auto_client_open_interval);
else
config.jack_auto_client_open_interval = value;
int fill_bytes = soundio_ring_buffer_fill_count(ring_buffer);
int fill_count = fill_bytes / outstream->bytes_per_frame;
- debug(3, "[--->>] frame_count_min: %d , frame_count_max: %d , fill_bytes: %d , fill_count: %d , "
- "outstream->bytes_per_frame: %d",
+ debug(3,
+ "[--->>] frame_count_min: %d , frame_count_max: %d , fill_bytes: %d , fill_count: %d , "
+ "outstream->bytes_per_frame: %d",
frame_count_min, frame_count_max, fill_bytes, fill_count, outstream->bytes_per_frame);
if (frame_count_min > fill_count) {
if (UDPPortIndex == 0)
UDPPortIndex = config.udp_port_base;
else if (UDPPortIndex == (config.udp_port_base + config.udp_port_range - 1))
- UDPPortIndex = config.udp_port_base + 3; // avoid wrapping back to the first three, as they can be assigned by resetFreeUDPPort without checking
+ UDPPortIndex = config.udp_port_base + 3; // avoid wrapping back to the first three, as they can
+ // be assigned by resetFreeUDPPort without checking
else
UDPPortIndex++;
return UDPPortIndex;
#ifdef CONFIG_OPENSSL
char *base64_enc(uint8_t *input, int length) {
- int oldState;
+ int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
BIO *bmem, *b64;
BUF_MEM *bptr;
}
uint8_t *base64_dec(char *input, int *outlen) {
- int oldState;
+ int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
BIO *bmem, *b64;
int inlen = strlen(input);
#ifdef CONFIG_OPENSSL
uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) {
- int oldState;
+ int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
RSA *rsa = NULL;
if (!rsa) {
void command_stop(void) {
// this has a cancellation point if waiting is enabled
if (config.cmd_stop)
- command_execute(config.cmd_stop,"",config.cmd_blocking);
+ command_execute(config.cmd_stop, "", config.cmd_blocking);
}
// this is for reading an unsigned 32 bit number, such as an RTP timestamp
double vol2attn(double vol, long max_db, long min_db) {
-// We use a little coordinate geometry to build a transfer function from the volume passed in to
-// the device's dynamic range. (See the diagram in the documents folder.) The x axis is the
-// "volume in" which will be from -30 to 0. The y axis will be the "volume out" which will be from
-// the bottom of the range to the top. We build the transfer function from one or more lines. We
-// characterise each line with two numbers: the first is where on x the line starts when y=0 (x
-// can be from 0 to -30); the second is where on y the line stops when when x is -30. thus, if the
-// line was characterised as {0,-30}, it would be an identity transfer. Assuming, for example, a
-// dynamic range of lv=-60 to hv=0 Typically we'll use three lines -- a three order transfer
-// function First: {0,30} giving a gentle slope -- the 30 comes from half the dynamic range
-// Second: {-5,-30-(lv+30)/2} giving a faster slope from y=0 at x=-12 to y=-42.5 at x=-30
-// Third: {-17,lv} giving a fast slope from y=0 at x=-19 to y=-60 at x=-30
+ // We use a little coordinate geometry to build a transfer function from the volume passed in to
+ // the device's dynamic range. (See the diagram in the documents folder.) The x axis is the
+ // "volume in" which will be from -30 to 0. The y axis will be the "volume out" which will be from
+ // the bottom of the range to the top. We build the transfer function from one or more lines. We
+ // characterise each line with two numbers: the first is where on x the line starts when y=0 (x
+ // can be from 0 to -30); the second is where on y the line stops when when x is -30. thus, if the
+ // line was characterised as {0,-30}, it would be an identity transfer. Assuming, for example, a
+ // dynamic range of lv=-60 to hv=0 Typically we'll use three lines -- a three order transfer
+ // function First: {0,30} giving a gentle slope -- the 30 comes from half the dynamic range
+ // Second: {-5,-30-(lv+30)/2} giving a faster slope from y=0 at x=-12 to y=-42.5 at x=-30
+ // Third: {-17,lv} giving a fast slope from y=0 at x=-19 to y=-60 at x=-30
#define order 3
et = (et * 1000000) >> 32; // microseconds
char errstr[1000];
if (r == ETIMEDOUT)
- debug(debuglevel, "timed out waiting for a mutex, having waiting %f seconds, with a maximum "
- "waiting time of %d microseconds. \"%s\".",
+ debug(debuglevel,
+ "timed out waiting for a mutex, having waiting %f seconds, with a maximum "
+ "waiting time of %d microseconds. \"%s\".",
(1.0 * et) / 1000000, dally_time, debugmessage);
else
debug(debuglevel, "error %d: \"%s\" waiting for a mutex: \"%s\".", r,
double audio_backend_buffer_interpolation_threshold_in_seconds; // below this, soxr interpolation
// will not occur -- it'll be
// basic interpolation instead.
- double audio_backend_silence_threshold; // below this, silence will be added to the output buffer
+ double audio_backend_silence_threshold; // below this, silence will be added to the output buffer
double audio_backend_silence_scan_interval; // check the threshold this often
-
+
double audio_backend_latency_offset; // this will be the offset in seconds to compensate for any
// fixed latency there might be in the audio path
double audio_backend_silent_lead_in_time; // the length of the silence that should precede a play.
- double active_mode_timeout; // the amount of time from when play ends to when the system leaves into the "active" mode.
- uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's
- // native range.
+ double active_mode_timeout; // the amount of time from when play ends to when the system leaves
+ // into the "active" mode.
+ uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's
+ // native range.
enum sps_format_t output_format;
enum volume_control_profile_type volume_control_profile;
int output_rate;
}
static const struct http_funcs responseFuncs = {
- response_realloc, response_body, response_header, response_code,
+ response_realloc,
+ response_body,
+ response_header,
+ response_code,
};
// static pthread_mutex_t dacp_conversation_lock = PTHREAD_MUTEX_INITIALIZER;
// debug(1,"Sent command\"%s\" with a response body of size %d.",command,response.size);
// debug(1,"dacp_conversation_lock released.");
} else {
- debug(3, "dacp_send_command: could not acquire a lock on the dacp transmit/receive section "
- "when attempting to "
- "send the command \"%s\". Possible timeout?",
+ debug(3,
+ "dacp_send_command: could not acquire a lock on the dacp transmit/receive section "
+ "when attempting to "
+ "send the command \"%s\". Possible timeout?",
command);
response.code = 494; // This client is already busy
}
void dacp_monitor_port_update_callback(char *dacp_id, uint16_t port) {
debug_mutex_lock(&dacp_server_information_lock, 500000, 2);
- debug(3, "dacp_monitor_port_update_callback with Remote ID \"%s\", target ID \"%s\" and port "
- "number %d.",
+ debug(3,
+ "dacp_monitor_port_update_callback with Remote ID \"%s\", target ID \"%s\" and port "
+ "number %d.",
dacp_id, dacp_server.dacp_id, port);
if (strcmp(dacp_id, dacp_server.dacp_id) == 0) {
dacp_server.port = port;
(metadata_store.advanced_dacp_server_active != 0);
metadata_store.dacp_server_active = 0;
metadata_store.advanced_dacp_server_active = 0;
- debug(2, "setting dacp_server_active and advanced_dacp_server_active to 0 with an update "
- "flag value of %d",
+ debug(2,
+ "setting dacp_server_active and advanced_dacp_server_active to 0 with an update "
+ "flag value of %d",
ch);
metadata_hub_modify_epilog(ch);
while (dacp_server.scan_enable == 0) {
}
gboolean notify_disable_standby_callback(ShairportSync *skeleton,
- __attribute__((unused)) gpointer user_data) {
+ __attribute__((unused)) gpointer user_data) {
// debug(1, "\"notify_disable_standby_callback\" called.");
if (shairport_sync_get_disable_standby(skeleton)) {
debug(1, ">> activating disable standby");
G_CALLBACK(notify_alacdecoder_callback), NULL);
g_signal_connect(shairportSyncSkeleton, "notify::volume-control-profile",
G_CALLBACK(notify_volume_control_profile_callback), NULL);
- g_signal_connect(shairportSyncSkeleton, "notify::disable-standby",
+ g_signal_connect(shairportSyncSkeleton, "notify::disable-standby",
G_CALLBACK(notify_disable_standby_callback), NULL);
-g_signal_connect(shairportSyncSkeleton, "notify::loudness-filter-active",
+ g_signal_connect(shairportSyncSkeleton, "notify::loudness-filter-active",
G_CALLBACK(notify_loudness_filter_active_callback), NULL);
g_signal_connect(shairportSyncSkeleton, "notify::loudness-threshold",
G_CALLBACK(notify_loudness_threshold_callback), NULL);
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "mdns.h"
#include "common.h"
+#include "mdns.h"
#include <arpa/inet.h>
#include <dns_sd.h>
#include <stdlib.h>
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "mdns.h"
#include "common.h"
+#include "mdns.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
char *path = NULL; // this will be what is returned
uint8_t img_md5[16];
-// uint8_t ap_md5[16];
+ // uint8_t ap_md5[16];
#ifdef CONFIG_SSL
MD5_CTX ctx;
enum play_status_type
player_state; // this is the state of the actual player itself, which can be a bit noisy.
- enum active_mode_type
- active_state;
+ enum active_mode_type active_state;
int speaker_volume; // this is the actual speaker volume, allowing for the main volume and the
// speaker volume control
}
if (outsize > toutsize) {
- debug(2, "Output from alac_decode larger (%d bytes, not frames) than expected (%d bytes) -- "
- "truncated, but buffer overflow possible! Encrypted = %d.",
+ debug(2,
+ "Output from alac_decode larger (%d bytes, not frames) than expected (%d bytes) -- "
+ "truncated, but buffer overflow possible! Encrypted = %d.",
outsize, toutsize, conn->stream.encrypted);
reply = -1; // output packet is the wrong size
}
*destlen = outsize / conn->input_bytes_per_frame;
if ((outsize % conn->input_bytes_per_frame) != 0)
- debug(1, "Number of audio frames (%d) does not correspond exactly to the number of bytes (%d) "
- "and the audio frame size (%d).",
+ debug(1,
+ "Number of audio frames (%d) does not correspond exactly to the number of bytes (%d) "
+ "and the audio frame size (%d).",
*destlen, outsize, conn->input_bytes_per_frame);
return reply;
}
if ((conn->flush_rtp_timestamp != 0) && (actual_timestamp != conn->flush_rtp_timestamp) &&
(modulo_32_offset(actual_timestamp, conn->flush_rtp_timestamp) <
conn->input_rate * 10)) { // if it's less than 10 seconds
- debug(3, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %" PRIu32
- ", flushing to "
- "timestamp: %" PRIu32 ".",
+ debug(3,
+ "Dropping flushed packet in player_put_packet, seqno %u, timestamp %" PRIu32
+ ", flushing to "
+ "timestamp: %" PRIu32 ".",
seqno, actual_timestamp, conn->flush_rtp_timestamp);
conn->initial_reference_time = 0;
conn->initial_reference_timestamp = 0;
(curframe->given_timestamp != conn->flush_rtp_timestamp) &&
(modulo_32_offset(curframe->given_timestamp, conn->flush_rtp_timestamp) <
conn->input_rate * 10)) { // if it's less than ten seconds
- debug(3, "Dropping flushed packet in buffer_get_frame, seqno %u, timestamp %" PRIu32
- ", flushing to "
- "timestamp: %" PRIu32 ".",
+ debug(3,
+ "Dropping flushed packet in buffer_get_frame, seqno %u, timestamp %" PRIu32
+ ", flushing to "
+ "timestamp: %" PRIu32 ".",
curframe->sequence_number, curframe->given_timestamp, conn->flush_rtp_timestamp);
curframe->ready = 0;
curframe->resend_level = 0;
frame_to_local_time(conn->first_packet_timestamp + conn->latency +
(uint32_t)(config.audio_backend_latency_offset *
conn->input_rate), // this will go modulo 2^32
- &should_be_time,
- conn);
+ &should_be_time, conn);
conn->first_packet_time_to_play = should_be_time;
frame_to_local_time(conn->first_packet_timestamp + conn->latency +
(uint32_t)(config.audio_backend_latency_offset *
conn->input_rate), // this should go modulo 2^32
- &should_be_time,
- conn);
+ &should_be_time, conn);
conn->first_packet_time_to_play = should_be_time;
// this might happen if a big clock adjustment was made at just the wrong
// time.
- debug(1, "Run a bit past the exact start time by %" PRId64
- " frames with a DAC delay of %ld frames.",
+ debug(1,
+ "Run a bit past the exact start time by %" PRId64
+ " frames with a DAC delay of %ld frames.",
-exact_frame_gap, dac_delay);
if (config.output->flush)
config.output->flush();
(uint32_t)(config.audio_backend_latency_offset * conn->input_rate) -
(uint32_t)(config.audio_backend_buffer_desired_length *
conn->input_rate), // this will go modulo 2^32
- &time_to_play,
- conn);
+ &time_to_play, conn);
if (local_time_now >= time_to_play) {
do_wait = 0;
}
void *player_thread_func(void *arg) {
- rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+ rtsp_conn_info *conn = (rtsp_conn_info *)arg;
// pthread_cleanup_push(player_thread_initial_cleanup_handler, arg);
conn->packet_count = 0;
conn->packet_count_since_flush = 0;
// if ((input_rate!=config.output_rate) || (input_bit_depth!=output_bit_depth)) {
// debug(1,"Define tbuf of length
// %d.",output_bytes_per_frame*(max_frames_per_packet*output_sample_ratio+max_frame_size_change));
- conn->tbuf =
- malloc(sizeof(int32_t) * 2 * (conn->max_frames_per_packet * conn->output_sample_ratio +
- conn->max_frame_size_change));
+ conn->tbuf = malloc(
+ sizeof(int32_t) * 2 *
+ (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change));
if (conn->tbuf == NULL)
die("Failed to allocate memory for the transition buffer.");
// initialise this, because soxr stuffing might be chosen later
- conn->sbuf =
- malloc(sizeof(int32_t) * 2 * (conn->max_frames_per_packet * conn->output_sample_ratio +
- conn->max_frame_size_change));
+ conn->sbuf = malloc(
+ sizeof(int32_t) * 2 *
+ (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change));
if (conn->sbuf == NULL)
die("Failed to allocate memory for the sbuf buffer.");
SUCCESSOR(conn->last_seqno_read); // int32_t from seq_t, i.e. uint16_t, so okay.
if (inframe->sequence_number !=
conn->last_seqno_read) { // seq_t, ei.e. uint16_t and int32_t, so okay
- debug(2, "Player: packets out of sequence: expected: %u, got: %u, with ab_read: %u "
- "and ab_write: %u.",
+ debug(2,
+ "Player: packets out of sequence: expected: %u, got: %u, with ab_read: %u "
+ "and ab_write: %u.",
conn->last_seqno_read, inframe->sequence_number, conn->ab_read, conn->ab_write);
conn->last_seqno_read = inframe->sequence_number; // reset warning...
}
#ifdef CONFIG_CONVOLUTION
|| config.convolution
#endif
- ) {
+ ) {
int32_t *tbuf32 = (int32_t *)conn->tbuf;
float fbuf_l[inbuflength];
float fbuf_r[inbuflength];
if ((config.output->delay)) {
if (config.no_sync == 0) {
- inform("%*.2f," /* Sync error in milliseconds */
- "%*.1f," /* net correction in ppm */
- "%*.1f," /* corrections in ppm */
- "%*d," /* total packets */
- "%*" PRIu64 "," /* missing packets */
- "%*" PRIu64 "," /* late packets */
- "%*" PRIu64 "," /* too late packets */
- "%*" PRIu64 "," /* resend requests */
- "%*" PRId64 "," /* min DAC queue size */
- "%*" PRId32 "," /* min buffer occupancy */
- "%*" PRId32 "," /* max buffer occupancy */
- "%*.2f," /* source nominal frame rate */
- "%*.2f," /* source actual (average) frame rate */
- "%*.2f," /* output frame rate */
- "%*.2f," /* source clock drift */
- "%*d," /* source clock drift sample count */
- "%*.2f", /* rough calculated correction in ppm */
- 10,
- 1000 * moving_average_sync_error / config.output_rate, 10,
- moving_average_correction * 1000000 / (352 * conn->output_sample_ratio),
- 10, moving_average_insertions_plus_deletions * 1000000 /
- (352 * conn->output_sample_ratio),
- 12, play_number, 7, conn->missing_packets, 7, conn->late_packets, 7,
- conn->too_late_packets, 7, conn->resend_requests, 7,
- minimum_dac_queue_size, 5, minimum_buffer_occupancy, 5,
- maximum_buffer_occupancy, 11, conn->remote_frame_rate, 11,
- conn->input_frame_rate, 11, conn->frame_rate, 10,
- (conn->local_to_remote_time_gradient - 1.0) * 1000000, 6,
- conn->local_to_remote_time_gradient_sample_count, 10,
- (conn->frame_rate > 0.0)
- ? ((conn->frame_rate -
- conn->remote_frame_rate * conn->output_sample_ratio *
- conn->local_to_remote_time_gradient) *
- 1000000) /
- conn->frame_rate
- : 0.0);
+ inform(
+ "%*.2f," /* Sync error in milliseconds */
+ "%*.1f," /* net correction in ppm */
+ "%*.1f," /* corrections in ppm */
+ "%*d," /* total packets */
+ "%*" PRIu64 "," /* missing packets */
+ "%*" PRIu64 "," /* late packets */
+ "%*" PRIu64 "," /* too late packets */
+ "%*" PRIu64 "," /* resend requests */
+ "%*" PRId64 "," /* min DAC queue size */
+ "%*" PRId32 "," /* min buffer occupancy */
+ "%*" PRId32 "," /* max buffer occupancy */
+ "%*.2f," /* source nominal frame rate */
+ "%*.2f," /* source actual (average) frame rate */
+ "%*.2f," /* output frame rate */
+ "%*.2f," /* source clock drift */
+ "%*d," /* source clock drift sample count */
+ "%*.2f", /* rough calculated correction in ppm */
+ 10, 1000 * moving_average_sync_error / config.output_rate, 10,
+ moving_average_correction * 1000000 / (352 * conn->output_sample_ratio), 10,
+ moving_average_insertions_plus_deletions * 1000000 /
+ (352 * conn->output_sample_ratio),
+ 12, play_number, 7, conn->missing_packets, 7, conn->late_packets, 7,
+ conn->too_late_packets, 7, conn->resend_requests, 7, minimum_dac_queue_size,
+ 5, minimum_buffer_occupancy, 5, maximum_buffer_occupancy, 11,
+ conn->remote_frame_rate, 11, conn->input_frame_rate, 11, conn->frame_rate, 10,
+ (conn->local_to_remote_time_gradient - 1.0) * 1000000, 6,
+ conn->local_to_remote_time_gradient_sample_count, 10,
+ (conn->frame_rate > 0.0)
+ ? ((conn->frame_rate - conn->remote_frame_rate *
+ conn->output_sample_ratio *
+ conn->local_to_remote_time_gradient) *
+ 1000000) /
+ conn->frame_rate
+ : 0.0);
} else {
inform("%*.2f," /* Sync error in milliseconds */
"%*d," /* total packets */
"%*.2f," /* source actual (average) frame rate */
"%*.2f," /* source clock drift */
"%*d", /* source clock drift sample count */
- 10,
- 1000 * moving_average_sync_error / config.output_rate, 12, play_number, 7,
- conn->missing_packets, 7, conn->late_packets, 7, conn->too_late_packets, 7,
- conn->resend_requests, 7, minimum_dac_queue_size, 5,
+ 10, 1000 * moving_average_sync_error / config.output_rate, 12, play_number,
+ 7, conn->missing_packets, 7, conn->late_packets, 7, conn->too_late_packets,
+ 7, conn->resend_requests, 7, minimum_dac_queue_size, 5,
minimum_buffer_occupancy, 5, maximum_buffer_occupancy, 11,
conn->remote_frame_rate, 11, conn->input_frame_rate, 10,
(conn->local_to_remote_time_gradient - 1.0) * 1000000, 6,
"%*.2f," /* source actual (average) frame rate */
"%*.2f," /* source clock drift */
"%*d", /* source clock drift sample count */
- 10,
- 1000 * moving_average_sync_error / config.output_rate, 12, play_number, 7,
- conn->missing_packets, 7, conn->late_packets, 7, conn->too_late_packets, 7,
- conn->resend_requests, 5, minimum_buffer_occupancy, 5,
+ 10, 1000 * moving_average_sync_error / config.output_rate, 12, play_number,
+ 7, conn->missing_packets, 7, conn->late_packets, 7, conn->too_late_packets,
+ 7, conn->resend_requests, 5, minimum_buffer_occupancy, 5,
maximum_buffer_occupancy, 11, conn->remote_frame_rate, 11,
conn->input_frame_rate, 10,
(conn->local_to_remote_time_gradient - 1.0) * 1000000, 6,
if (config.buffer_start_fill > BUFFER_FRAMES)
die("specified buffer starting fill %d > buffer size %d", config.buffer_start_fill,
BUFFER_FRAMES);
- activity_monitor_signify_activity(1); // active, and should be before play's command hook, command_start()
+ activity_monitor_signify_activity(
+ 1); // active, and should be before play's command hook, command_start()
command_start();
pthread_t *pt = malloc(sizeof(pthread_t));
if (pt == NULL)
stat_mean += stat_delta / stat_n;
stat_M2 += stat_delta * (time_interval_us - stat_mean);
if (stat_n % 2500 == 0) {
- debug(2, "Packet reception interval stats: mean, standard deviation and max for the last "
- "2,500 packets in microseconds: %10.1f, %10.1f, %10.1f.",
+ debug(2,
+ "Packet reception interval stats: mean, standard deviation and max for the last "
+ "2,500 packets in microseconds: %10.1f, %10.1f, %10.1f.",
stat_mean, sqrtf(stat_M2 / (stat_n - 1)), longest_packet_time_interval_us);
stat_n = 0;
stat_mean = 0.0;
if (la != conn->latency) {
conn->latency = la;
- debug(3, "New latency detected: %" PRIu32 ", sync latency: %" PRIu32
- ", minimum latency: %" PRIu32 ", maximum "
- "latency: %" PRIu32 ", fixed offset: %" PRIu32 ".",
+ debug(3,
+ "New latency detected: %" PRIu32 ", sync latency: %" PRIu32
+ ", minimum latency: %" PRIu32 ", maximum "
+ "latency: %" PRIu32 ", fixed offset: %" PRIu32 ".",
la, sync_rtp_timestamp - rtp_timestamp_less_latency, conn->minimum_latency,
conn->maximum_latency, config.fixedLatencyOffset);
}
(struct sockaddr *)&conn->rtp_client_control_socket, msgsize) == -1) {
char em[1024];
strerror_r(errno, em, sizeof(em));
- debug(1, "Error %d using sendto to an audio socket: \"%s\". Backing off for 1/16th of a "
- "second.",
+ debug(1,
+ "Error %d using sendto to an audio socket: \"%s\". Backing off for 1/16th of a "
+ "second.",
errno, em);
conn->rtp_time_of_last_resend_request_error_fp = time_of_sending_fp;
} else {
if (time_since_last_bark >= ct) {
conn->watchdog_barks++;
if (conn->watchdog_barks == 1) {
- debug(1, "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
- "of the heart\".",
+ debug(1,
+ "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
+ "of the heart\".",
conn->connection_number);
conn->stop = 1;
pthread_cancel(conn->thread);
} else if (conn->watchdog_barks == 3) {
if ((config.cmd_unfixable) && (conn->unfixable_error_reported == 0)) {
conn->unfixable_error_reported = 1;
- command_execute(config.cmd_unfixable, "unable_to_cancel_play_session",1);
+ command_execute(config.cmd_unfixable, "unable_to_cancel_play_session", 1);
} else {
warn("an unrecoverable error, \"unable_to_cancel_play_session\", has been detected.",
conn->connection_number);
}
void msg_retain(rtsp_message *msg) {
- int rc = pthread_mutex_lock(&reference_counter_lock);
- if (rc)
- debug(1, "Error %d locking reference counter lock");
- if (msg > (rtsp_message *) 0x00010000) {
+ int rc = pthread_mutex_lock(&reference_counter_lock);
+ if (rc)
+ debug(1, "Error %d locking reference counter lock");
+ if (msg > (rtsp_message *)0x00010000) {
msg->referenceCount++;
// debug(1,"msg_retain -- item %d reference count %d.", msg->index_number, msg->referenceCount);
rc = pthread_mutex_unlock(&reference_counter_lock);
if (rc)
debug(1, "Error %d unlocking reference counter lock");
} else {
- debug(1, "invalid rtsp_message pointer 0x%x passed to retain", (uintptr_t) msg);
+ debug(1, "invalid rtsp_message pointer 0x%x passed to retain", (uintptr_t)msg);
}
}
uintptr_t index = (msg->index_number) & 0xFFFF;
if (index == 0)
index = 0x10000; // ensure it doesn't fold to zero.
- *msgh = (rtsp_message *)(index); // put a version of the index number of the freed message in here
+ *msgh =
+ (rtsp_message *)(index); // put a version of the index number of the freed message in here
free(msg);
} else {
- // debug(1,"msg_free item %d -- decrement reference to %d.",msg->index_number,msg->referenceCount);
+ // debug(1,"msg_free item %d -- decrement reference to
+ // %d.",msg->index_number,msg->referenceCount);
}
} else if (*msgh != NULL) {
- debug(1, "msg_free: error attempting to free an allocated but already-freed rtsp_message, number %d.",(uintptr_t)*msgh);
+ debug(1,
+ "msg_free: error attempting to free an allocated but already-freed rtsp_message, number "
+ "%d.",
+ (uintptr_t)*msgh);
}
debug_mutex_unlock(&reference_counter_lock, 0);
}
rtsp_message *resp) {
debug(3, "Connection %d: OPTIONS", conn->connection_number);
resp->respcode = 200;
- msg_add_header(resp, "Public", "ANNOUNCE, SETUP, RECORD, "
- "PAUSE, FLUSH, TEARDOWN, "
- "OPTIONS, GET_PARAMETER, SET_PARAMETER");
+ msg_add_header(resp, "Public",
+ "ANNOUNCE, SETUP, RECORD, "
+ "PAUSE, FLUSH, TEARDOWN, "
+ "OPTIONS, GET_PARAMETER, SET_PARAMETER");
}
void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
char *ct = msg_get_header(req, "Content-Type");
if (ct) {
-// debug(2, "SET_PARAMETER Content-Type:\"%s\".", ct);
+ // debug(2, "SET_PARAMETER Content-Type:\"%s\".", ct);
#ifdef CONFIG_METADATA
// It seems that the rtptime of the message is used as a kind of an ID that
uint8_t digest_urp[16], digest_mu[16], digest_total[16];
-
#ifdef CONFIG_OPENSSL
MD5_CTX ctx;
if (strcmp(req->method, "OPTIONS") !=
0) // the options message is very common, so don't log it until level 3
debug_level = 2;
- debug(debug_level, "Connection %d: Received an RTSP Packet of type \"%s\":",
- conn->connection_number, req->method),
+ debug(debug_level,
+ "Connection %d: Received an RTSP Packet of type \"%s\":", conn->connection_number,
+ req->method),
debug_print_msg_headers(debug_level, req);
apple_challenge(conn->fd, req, resp);
if (conn->stop == 0) {
int err = msg_write_response(conn->fd, resp);
if (err) {
- debug(1, "Connection %d: Unable to write an RTSP message response. Terminating the "
- "connection.",
+ debug(1,
+ "Connection %d: Unable to write an RTSP message response. Terminating the "
+ "connection.",
conn->connection_number);
struct linger so_linger;
so_linger.l_onoff = 1; // "true"
char errorstring[1024];
strerror_r(ret, (char *)errorstring, sizeof(errorstring));
die("Connection %d: cannot create an RTSP conversation thread. Error %d: \"%s\".",
- conn->connection_number, ret, (char *)errorstring);
+ conn->connection_number, ret, (char *)errorstring);
}
debug(3, "Successfully created RTSP receiver thread %d.", conn->connection_number);
conn->running = 1; // this must happen before the thread is tracked
#include <glib.h>
#endif
+#include "activity_monitor.h"
#include "common.h"
#include "mdns.h"
#include "rtp.h"
#include "rtsp.h"
-#include "activity_monitor.h"
#if defined(CONFIG_DACP_CLIENT)
#include "dacp.h"
config.cmd_stop = (char *)str;
}
- if (config_lookup_string(config.cfg, "sessioncontrol.run_this_before_entering_active_mode", &str)) {
+ if (config_lookup_string(config.cfg, "sessioncontrol.run_this_before_entering_active_mode",
+ &str)) {
config.cmd_active_start = (char *)str;
}
- if (config_lookup_string(config.cfg, "sessioncontrol.run_this_after_exiting_active_mode", &str)) {
+ if (config_lookup_string(config.cfg, "sessioncontrol.run_this_after_exiting_active_mode",
+ &str)) {
config.cmd_active_stop = (char *)str;
}
if (config_lookup_float(config.cfg, "sessioncontrol.active_mode_timeout", &dvalue)) {
if (dvalue < 0.0)
- warn("Invalid value \"%f\" for sessioncontrol.active_mode_timeout. It must be positive. The default of %f will be used instead.",
- dvalue, config.active_mode_timeout);
+ warn("Invalid value \"%f\" for sessioncontrol.active_mode_timeout. It must be positive. "
+ "The default of %f will be used instead.",
+ dvalue, config.active_mode_timeout);
else
config.active_mode_timeout = dvalue;
}
-
- if (config_lookup_string(config.cfg,
+ if (config_lookup_string(config.cfg,
"sessioncontrol.run_this_if_an_unfixable_error_is_detected", &str)) {
config.cmd_unfixable = (char *)str;
}
#endif
activity_monitor_stop(0);
-
+
if (config.output->deinit) {
debug(1, "Deinitialise the audio backend.");
config.output->deinit();
/* Print out options */
debug(1, "log verbosity is %d.", debuglev);
debug(1, "disable resend requests is %s.", config.disable_resend_requests ? "on" : "off");
- debug(1, "diagnostic_drop_packet_fraction is %f. A value of 0.0 means no packets will be dropped "
- "deliberately.",
+ debug(1,
+ "diagnostic_drop_packet_fraction is %f. A value of 0.0 means no packets will be dropped "
+ "deliberately.",
config.diagnostic_drop_packet_fraction);
debug(1, "statistics_requester status is %d.", config.statistics_requested);
debug(1, "daemon status is %d.", config.daemonise);
uint8_t ap_md5[16];
#ifdef CONFIG_OPENSSL
- // can't imagine this is necessary, but here it is anyway
+ // can't imagine this is necessary, but here it is anyway
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
MD5_CTX ctx;
assert(s != NULL);
struct timeval tv = {
- .tv_sec = 0, .tv_usec = 500 * 1000,
+ .tv_sec = 0,
+ .tv_usec = 500 * 1000,
};
s->stop_flag = 1;