Continuing to check the high-volume limiter. Add configuration file settings for default and threshold volume settings and timeout. Include in diagnostics, set tentative defaults.
This commit is contained in:
@@ -1704,33 +1704,31 @@ void statistics_item(const char *heading, const char *format, ...) {
|
||||
|
||||
double suggested_volume(rtsp_conn_info *conn) {
|
||||
double response = config.airplay_volume;
|
||||
if (conn) {
|
||||
if (conn->own_airplay_volume_set != 0) {
|
||||
response = conn->own_airplay_volume;
|
||||
} else if (config.airplay_volume > config.high_threshold_airplay_volume) {
|
||||
int64_t volume_validity_time = config.limit_to_high_volume_threshold_time_in_minutes;
|
||||
// zero means never check the volume
|
||||
if (volume_validity_time != 0) {
|
||||
// If the volume is higher than the high volume threshold
|
||||
// and enough time has gone past, suggest the default volume.
|
||||
uint64_t time_now = get_absolute_time_in_ns();
|
||||
int64_t time_since_last_access_to_volume_info =
|
||||
time_now - config.last_access_to_volume_info_time;
|
||||
if ((conn != NULL) && (conn->own_airplay_volume_set != 0)) {
|
||||
response = conn->own_airplay_volume;
|
||||
} else if (config.airplay_volume > config.high_threshold_airplay_volume) {
|
||||
int64_t volume_validity_time = config.limit_to_high_volume_threshold_time_in_minutes;
|
||||
// zero means never check the volume
|
||||
if (volume_validity_time != 0) {
|
||||
// If the volume is higher than the high volume threshold
|
||||
// and enough time has gone past, suggest the default volume.
|
||||
uint64_t time_now = get_absolute_time_in_ns();
|
||||
int64_t time_since_last_access_to_volume_info =
|
||||
time_now - config.last_access_to_volume_info_time;
|
||||
|
||||
volume_validity_time = volume_validity_time * 60; // to seconds
|
||||
volume_validity_time = volume_validity_time * 1000000000; // to nanoseconds
|
||||
volume_validity_time = volume_validity_time * 60; // to seconds
|
||||
volume_validity_time = volume_validity_time * 1000000000; // to nanoseconds
|
||||
|
||||
if ((config.airplay_volume > config.high_threshold_airplay_volume) &&
|
||||
((config.last_access_to_volume_info_time == 0) ||
|
||||
(time_since_last_access_to_volume_info > volume_validity_time))) {
|
||||
if ((config.airplay_volume > config.high_threshold_airplay_volume) &&
|
||||
((config.last_access_to_volume_info_time == 0) ||
|
||||
(time_since_last_access_to_volume_info > volume_validity_time))) {
|
||||
|
||||
debug(2,
|
||||
"the current volume %.6f is higher than the high volume threshold %.6f, so the "
|
||||
"default volume %.6f is suggested.",
|
||||
config.airplay_volume, config.high_threshold_airplay_volume,
|
||||
config.default_airplay_volume);
|
||||
response = config.default_airplay_volume;
|
||||
}
|
||||
debug(2,
|
||||
"the current volume %.6f is higher than the high volume threshold %.6f, so the "
|
||||
"default volume %.6f is suggested.",
|
||||
config.airplay_volume, config.high_threshold_airplay_volume,
|
||||
config.default_airplay_volume);
|
||||
response = config.default_airplay_volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -757,19 +757,24 @@ void cleanup_threads(void) {
|
||||
free(conns[i]);
|
||||
conns[i] = NULL;
|
||||
}
|
||||
if (conns[i] != NULL)
|
||||
if (conns[i] != NULL) {
|
||||
debug(1, "Airplay Volume for connection %d is %.6f.", conns[i]->connection_number,
|
||||
suggested_volume(conns[i]));
|
||||
connection_count++;
|
||||
}
|
||||
}
|
||||
debug_mutex_unlock(&conns_lock, 3);
|
||||
|
||||
if (old_connection_count != connection_count) {
|
||||
if (connection_count == 0)
|
||||
if (connection_count == 0) {
|
||||
debug(2, "No active connections.");
|
||||
else if (connection_count == 1)
|
||||
} else if (connection_count == 1)
|
||||
debug(2, "One active connection.");
|
||||
else
|
||||
debug(2, "%d active connections.", connection_count);
|
||||
old_connection_count = connection_count;
|
||||
}
|
||||
debug(1, "Airplay Volume for new connections is %.6f.", suggested_volume(NULL));
|
||||
}
|
||||
|
||||
// park a null at the line ending, and return the next line pointer
|
||||
@@ -5477,6 +5482,7 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
|
||||
FD_SET(sockfd[i], &fds);
|
||||
|
||||
ret = select(maxfd + 1, &fds, 0, 0, &tv);
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
@@ -43,9 +43,24 @@ general =
|
||||
// "standard" makes the volume change more quickly at lower volumes and slower at higher volumes.
|
||||
// "flat" makes the volume change at the same rate at all volumes.
|
||||
// volume_control_combined_hardware_priority = "no"; // when extending the volume range by combining the built-in software attenuator with the hardware mixer attenuator, set this to "yes" to reduce volume by using the hardware mixer first, then the built-in software attenuator.
|
||||
|
||||
// default_airplay_volume = 24.0; // this is the suggested volume after a reset or after the high_volume_threshold has been exceed and the high_volume_idle_timeout_in_minutes has passed
|
||||
|
||||
// The following settings are for dealing with potentially surprising high ("very loud") volume levels.
|
||||
// When a new play session starts, it usually requests a suggested volume level from Shairport Sync. This is normally the volume level of the last session.
|
||||
// This can cause unpleasant surprises if the last session was (a) very loud and (b) a long time ago.
|
||||
// Thus, the user could be unpleasantly surprised by the volume level of the new session.
|
||||
|
||||
// To deal with this, when the last session volume is "very loud", the following two settings will lower the suggested volume after a period of idleness:
|
||||
|
||||
// high_threshold_airplay_volume = -16.0; // airplay volume greater or equal to this is "very loud"
|
||||
// high_volume_idle_timeout_in_minutes = 0; // if the current volume is "very loud" and the device is not playing for more than this time, suggest the default volume for new connections instead of the current volume.
|
||||
// Note 1: This timeout is set to 0 by default to disable this feature. Set it to some positive number, e.g. 180 to activate the feature.
|
||||
// Note 2: Not all applications use the suggested volume: MacOS Music and Mac OS System Sounds use their own settings.
|
||||
|
||||
// run_this_when_volume_is_set = "/full/path/to/application/and/args"; // Run the specified application whenever the volume control is set or changed.
|
||||
// The desired AirPlay volume is appended to the end of the command line – leave a space if you want it treated as an extra argument.
|
||||
// AirPlay volume goes from 0 to -30 and -144 means "mute".
|
||||
// AirPlay volume goes from 0.0 to -30.0 and -144.0 means "mute".
|
||||
|
||||
// audio_backend_latency_offset_in_seconds = 0.0; // This is added to the latency requested by the player to delay or advance the output by a fixed amount.
|
||||
// Use it, for example, to compensate for a fixed delay in the audio back end.
|
||||
|
||||
+42
-2
@@ -471,8 +471,8 @@ int parse_options(int argc, char **argv) {
|
||||
-16.0; // if the volume exceeds this, reset to the default volume if idle for the
|
||||
// limit_to_high_volume_threshold_time_in_minutes time
|
||||
config.limit_to_high_volume_threshold_time_in_minutes =
|
||||
3 * 60; // after this time in minutes, if the volume is higher, use the default_airplay_volume volume
|
||||
// for new play sessions.
|
||||
0; // after this time in minutes, if the volume is higher, use the default_airplay_volume
|
||||
// volume for new play sessions.
|
||||
config.fixedLatencyOffset = 11025; // this sounds like it works properly.
|
||||
config.diagnostic_drop_packet_fraction = 0.0;
|
||||
config.active_state_timeout = 10.0;
|
||||
@@ -845,6 +845,37 @@ int parse_options(int argc, char **argv) {
|
||||
config.volume_max_db_set = 1;
|
||||
}
|
||||
|
||||
/* Get the optional default_volume setting. */
|
||||
if (config_lookup_float(config.cfg, "general.default_airplay_volume", &dvalue)) {
|
||||
// debug(1, "Default airplay volume setting of %f on the -30.0 to 0 scale", dvalue);
|
||||
if ((dvalue >= -30.0) && (dvalue <= 0.0)) {
|
||||
config.default_airplay_volume = dvalue;
|
||||
} else {
|
||||
warn("The default airplay volume setting must be between -30.0 and 0.0.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the optional high_volume_threshold setting. */
|
||||
if (config_lookup_float(config.cfg, "general.high_threshold_airplay_volume", &dvalue)) {
|
||||
// debug(1, "High threshold airplay volume setting of %f on the -30.0 to 0 scale", dvalue);
|
||||
if ((dvalue >= -30.0) && (dvalue <= 0.0)) {
|
||||
config.high_threshold_airplay_volume = dvalue;
|
||||
} else {
|
||||
warn("The high threshold airplay volume setting must be between -30.0 and 0.0.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the optional high volume idle tiomeout setting. */
|
||||
if (config_lookup_float(config.cfg, "general.high_volume_idle_timeout_in_minutes", &dvalue)) {
|
||||
// debug(1, "High high_volume_idle_timeout_in_minutes setting of %f", dvalue);
|
||||
if (dvalue >= 0.0) {
|
||||
config.limit_to_high_volume_threshold_time_in_minutes = dvalue;
|
||||
} else {
|
||||
warn("The high volume idle timeout in minutes setting must be 0.0 or greater. A setting "
|
||||
"of 0.0 disables the high volume check.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config_lookup_string(config.cfg, "general.run_this_when_volume_is_set", &str)) {
|
||||
config.cmd_set_volume = (char *)str;
|
||||
}
|
||||
@@ -2392,6 +2423,15 @@ int main(int argc, char **argv) {
|
||||
debug(1, "busy timeout time is %d.", config.timeout);
|
||||
debug(1, "drift tolerance is %f seconds.", config.tolerance);
|
||||
debug(1, "password is \"%s\".", strnull(config.password));
|
||||
debug(1, "default airplay volume is %.6f.", config.default_airplay_volume);
|
||||
debug(1, "high threshold airplay volume is %.6f.", config.high_threshold_airplay_volume);
|
||||
if (config.limit_to_high_volume_threshold_time_in_minutes == 0)
|
||||
debug(1, "check for higher-than-threshold volume for new play session is disabled.");
|
||||
else
|
||||
debug(1,
|
||||
"suggest default airplay volume for new play session instead of higher-than-threshold "
|
||||
"airplay volume after %d minutes.",
|
||||
config.limit_to_high_volume_threshold_time_in_minutes);
|
||||
debug(1, "ignore_volume_control is %d.", config.ignore_volume_control);
|
||||
if (config.volume_max_db_set)
|
||||
debug(1, "volume_max_db is %d.", config.volume_max_db);
|
||||
|
||||
Reference in New Issue
Block a user