From: Mike Brady Date: Sun, 5 Feb 2017 16:18:05 +0000 (+0000) Subject: Add volume_max_db setting which works on the hw mixer if it exists or the sw attenuat... X-Git-Tag: 3.0.d24~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a4a4ed22b72be845d1ab95102b3132bb3423133;p=thirdparty%2Fshairport-sync.git Add volume_max_db setting which works on the hw mixer if it exists or the sw attenuator otherwise. --- diff --git a/common.c b/common.c index cf1138a1..30b5e6f8 100644 --- a/common.c +++ b/common.c @@ -559,7 +559,7 @@ double vol2attn(double vol, long max_db, long min_db) { double vol_setting = 0; if ((vol <= 0.0) && (vol >= -30.0)) { - long range_db = max_db - min_db; // this will be a positive nunmber + long range_db = max_db - min_db; // this will be a positive number // debug(1,"Volume min %ddB, max %ddB, range %ddB.",min_db,max_db,range_db); // double first_slope = -3000.0; // this is the slope of the attenuation at the high end -- 30dB // for the full rotation. diff --git a/common.h b/common.h index d84de86d..af965e92 100644 --- a/common.h +++ b/common.h @@ -87,6 +87,8 @@ typedef struct { int udp_port_base; int udp_port_range; int ignore_volume_control; + int volume_max_db_set; // set to 1 if a maximum volume db has been set + int volume_max_db; int no_sync; // disable synchronisation, even if it's available int no_mmap; // disable use of mmap-based output, even if it's available double resyncthreshold; // if it get's out of whack my more than this number of seconds, resync. diff --git a/player.c b/player.c index df6e515e..c121969f 100644 --- a/player.c +++ b/player.c @@ -2259,16 +2259,6 @@ void player_volume(double airplay_volume) { int32_t hw_min_db, hw_max_db, hw_range_db, range_to_use, min_db, max_db; // hw_range_db is a flag; if 0 means no mixer - int32_t sw_min_db = -9630; - int32_t sw_max_db = 0; - int32_t sw_range_db = sw_max_db - sw_min_db; - int32_t desired_range_db; // this is used as a flag; if 0 means no desired range - - if (config.volume_range_db) - desired_range_db = (int32_t)trunc(config.volume_range_db * 100); - else - desired_range_db = 0; - if (config.output->parameters) { // have a hardware mixer config.output->parameters(&audio_information); @@ -2279,7 +2269,34 @@ void player_volume(double airplay_volume) { // don't have a hardware mixer hw_max_db = hw_min_db = hw_range_db = 0; } + + int32_t sw_min_db = -9630; + int32_t sw_max_db = 0; + int32_t sw_range_db = sw_max_db - sw_min_db; + int32_t desired_range_db = 0; // this is used as a flag; if 0 means no desired range + if (config.volume_range_db) + desired_range_db = (int32_t)trunc(config.volume_range_db * 100); + + if (config.volume_max_db_set) { + if (hw_range_db) { + if (((config.volume_max_db*100)hw_min_db)) { + hw_max_db = (int)config.volume_max_db*100; + hw_range_db = hw_max_db-hw_min_db; + } else { + inform("The volume_max_db setting is out of range of the hardware mixers's limits of %d dB to %d dB. It will be ignored.", (int)(hw_max_db/100), (int)(hw_min_db/100)); + } + } else { + if (((config.volume_max_db*100)sw_min_db)) { + sw_max_db = (int)config.volume_max_db*100; + sw_range_db = sw_max_db-sw_min_db; + } else { + inform("The volume_max_db setting is out of range of the software attenuation's limits of 0 dB to -96.3 dB. It will be ignored."); + } + } + } + + if (desired_range_db) { // debug(1,"An attenuation range of %d is requested.",desired_range_db); // we have a desired volume range. @@ -2322,6 +2339,16 @@ void player_volume(double airplay_volume) { } } +/* + if (config.volume_max_db_set) { + if ((config.volume_max_db*100<=max_db) && (config.volume_max_db*100>=min_db)) { + debug(1,"Reducing the maximum volume from %d to %d.",max_db/100,config.volume_max_db); + max_db = (int)(config.volume_max_db*100); + } else { + inform("The value of volume_max_db is invalid. It must be in the range %d to %d.",max_db,min_db); + } + } +*/ double hardware_attenuation, software_attenuation; double scaled_attenuation = hw_min_db + sw_min_db; diff --git a/shairport.c b/shairport.c index 5a147005..41520afe 100644 --- a/shairport.c +++ b/shairport.c @@ -474,6 +474,13 @@ int parse_options(int argc, char **argv) { else die("Invalid ignore_volume_control option choice \"%s\". It should be \"yes\" or \"no\""); } + + /* Get the optional volume_max_db setting. */ + if (config_lookup_float(config.cfg, "general.volume_max_db", &dvalue)) { + debug(1,"Max volume setting of %f dB",dvalue); + config.volume_max_db = dvalue; + config.volume_max_db_set = 1; + } /* Get the playback_mode setting */ if (config_lookup_string(config.cfg, "general.playback_mode", &str)) { @@ -491,9 +498,6 @@ int parse_options(int argc, char **argv) { die("Invalid playback_mode choice \"%s\". It should be \"stereo\" (default), \"mono\", " "\"reverse stereo\", \"both left\", \"both right\""); } - - - /* Get the interface to listen on, if specified Default is all interfaces */ /* we keep the interface name and the index */