Add support for max volume for AirPlay devices (raop)

This commit is contained in:
ejurgensen 2014-02-09 16:07:00 +01:00
parent 258163e6ce
commit 23a7e82a1f
4 changed files with 38 additions and 14 deletions

View File

@ -95,7 +95,7 @@ library {
# Local audio output # Local audio output
audio { audio {
# AirTunes name - used in the speaker list in Remote # Name - used in the speaker list in Remote
nickname = "Computer" nickname = "Computer"
# Audio device name for local audio output # Audio device name for local audio output
# card = "default" # card = "default"
@ -104,8 +104,11 @@ audio {
# mixer = "" # mixer = ""
} }
# Airport Express device # AirPlay/Airport Express device settings
#apex "ApEx" { #airplay "My AirPlay speaker" {
# AirTunes password # forked-daapd's volume goes to 11! If that's more than you can handle
# you can set a lower value here
# max_volume = 11
# AirPlay password
# password = "s1kr3t" # password = "s1kr3t"
#} #}

View File

@ -92,9 +92,10 @@ static cfg_opt_t sec_audio[] =
CFG_END() CFG_END()
}; };
/* ApEx device section structure */ /* AirPlay/ApEx device section structure */
static cfg_opt_t sec_apex[] = static cfg_opt_t sec_airplay[] =
{ {
CFG_INT("max_volume", 11, CFGF_NONE),
CFG_STR("password", NULL, CFGF_NONE), CFG_STR("password", NULL, CFGF_NONE),
CFG_END() CFG_END()
}; };
@ -105,7 +106,7 @@ static cfg_opt_t toplvl_cfg[] =
CFG_SEC("general", sec_general, CFGF_NONE), CFG_SEC("general", sec_general, CFGF_NONE),
CFG_SEC("library", sec_library, CFGF_NONE), CFG_SEC("library", sec_library, CFGF_NONE),
CFG_SEC("audio", sec_audio, CFGF_NONE), CFG_SEC("audio", sec_audio, CFGF_NONE),
CFG_SEC("apex", sec_apex, CFGF_MULTI | CFGF_TITLE), CFG_SEC("airplay", sec_airplay, CFGF_MULTI | CFGF_TITLE),
CFG_END() CFG_END()
}; };

View File

@ -3798,7 +3798,7 @@ static void
raop_device_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt) raop_device_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt)
{ {
struct raop_device *rd; struct raop_device *rd;
cfg_t *apex; cfg_t *airplay;
const char *p; const char *p;
char *at_name; char *at_name;
char *password; char *password;
@ -3904,9 +3904,9 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
{ {
DPRINTF(E_LOG, L_PLAYER, "AirPlay device %s is password-protected\n", name); DPRINTF(E_LOG, L_PLAYER, "AirPlay device %s is password-protected\n", name);
apex = cfg_gettsec(cfg, "apex", at_name); airplay = cfg_gettsec(cfg, "airplay", at_name);
if (apex) if (airplay)
password = cfg_getstr(apex, "password"); password = cfg_getstr(airplay, "password");
if (!password) if (!password)
DPRINTF(E_LOG, L_PLAYER, "No password given in config for AirPlay device %s\n", name); DPRINTF(E_LOG, L_PLAYER, "No password given in config for AirPlay device %s\n", name);

View File

@ -85,6 +85,9 @@
#define RAOP_MD_DELAY_STARTUP 15360 #define RAOP_MD_DELAY_STARTUP 15360
#define RAOP_MD_DELAY_SWITCH (RAOP_MD_DELAY_STARTUP * 2) #define RAOP_MD_DELAY_SWITCH (RAOP_MD_DELAY_STARTUP * 2)
/* This is an arbitrary value which just needs to be kept in sync with the config */
#define RAOP_CONFIG_MAX_VOLUME 11
struct raop_v2_packet struct raop_v2_packet
{ {
uint8_t clear[AIRTUNES_V2_PKT_LEN]; uint8_t clear[AIRTUNES_V2_PKT_LEN];
@ -2231,9 +2234,26 @@ raop_metadata_send(int id, uint64_t rtptime, uint64_t offset, int startup)
/* Volume handling */ /* Volume handling */
static float static float
raop_volume_convert(int volume) raop_volume_convert(int volume, char *name)
{ {
float raop_volume; float raop_volume;
cfg_t *airplay;
int max_volume;
max_volume = RAOP_CONFIG_MAX_VOLUME;
airplay = cfg_gettsec(cfg, "airplay", name);
if (airplay)
max_volume = cfg_getint(airplay, "max_volume");
if ((max_volume < 1) || (max_volume > RAOP_CONFIG_MAX_VOLUME))
{
DPRINTF(E_LOG, L_RAOP, "Config has bad max_volume (%d) for device %s, using default instead\n", max_volume, name);
max_volume = RAOP_CONFIG_MAX_VOLUME;
}
DPRINTF(E_DBG, L_RAOP, "Setting max_volume for device %s to %d\n", name, max_volume);
/* RAOP volume /* RAOP volume
* -144.0 is off * -144.0 is off
@ -2242,7 +2262,7 @@ raop_volume_convert(int volume)
if (volume == 0) if (volume == 0)
raop_volume = -144.0; raop_volume = -144.0;
else else
raop_volume = -30.0 + ((float)volume * 30.0) / 100.0; raop_volume = -30.0 + ((float)max_volume * (float)volume * 30.0) / (100.0 * RAOP_CONFIG_MAX_VOLUME);
return raop_volume; return raop_volume;
} }
@ -2262,7 +2282,7 @@ raop_set_volume_internal(struct raop_session *rs, int volume, evrtsp_req_cb cb)
return -1; return -1;
} }
raop_volume = raop_volume_convert(volume); raop_volume = raop_volume_convert(volume, rs->devname);
/* Don't let locales get in the way here */ /* Don't let locales get in the way here */
ret = evbuffer_add_printf(evbuf, "volume: %d.%06d\r\n", (int)raop_volume, -(int)(1000000.0 * (raop_volume - (int)raop_volume))); ret = evbuffer_add_printf(evbuf, "volume: %d.%06d\r\n", (int)raop_volume, -(int)(1000000.0 * (raop_volume - (int)raop_volume)));