Add a "run_this_when_volume_is_set" facility to call a program when the volume is set. The AirPlay volume is passed.

This commit is contained in:
Mike Brady
2017-04-23 12:37:11 +01:00
parent 9e3d6a1fb4
commit e37c277b0a
4 changed files with 56 additions and 1 deletions
+48
View File
@@ -32,6 +32,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
@@ -454,6 +455,53 @@ uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) {
}
#endif
void command_set_volume(double volume) {
if (config.cmd_set_volume) {
/*Spawn a child to run the program.*/
pid_t pid = fork();
if (pid == 0) { /* child process */
size_t command_buffer_size = strlen(config.cmd_set_volume)+32;
char* command_buffer = (char*)malloc(command_buffer_size);
if (command_buffer==NULL) {
inform("Couldn't allocate memory for set_volume argument string");
} else {
memset(command_buffer,0,command_buffer_size);
sprintf(command_buffer, "%s%f", config.cmd_set_volume,volume);
// debug(1,"command_buffer is \"%s\".",command_buffer);
int argC;
char **argV;
// debug(1,"set_volume command found.");
if (poptParseArgvString(command_buffer, &argC, (const char ***)&argV) !=
0) {
// note that argV should be free()'d after use, but we expect this fork to exit
// eventually.
warn("Can't decipher on-set-volume command arguments \"%s\".",command_buffer);
free(argV);
free(command_buffer);
} else {
free(command_buffer);
// debug(1,"Executing on-set-volume command %s with %d arguments.",argV[0],argC);
execv(argV[0], argV);
warn("Execution of on-set-volume command \"%s\" failed to start", config.cmd_set_volume);
// debug(1, "Error executing on-set-volume command %s", config.cmd_set_volume);
exit(127); /* only if execv fails */
}
}
} else {
if (config.cmd_blocking) { /* pid!=0 means parent process and if blocking is true, wait for
process to finish */
pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */
if (rc != pid) {
warn("Execution of on-set-volume command returned an error.");
debug(1, "on-set-volume command %s finished with error %d", config.cmd_set_volume,errno);
}
}
// debug(1,"Continue after on-set-volume command");
}
}
}
void command_start(void) {
if (config.cmd_start) {
/*Spawn a child to run the program.*/
+2 -1
View File
@@ -113,7 +113,7 @@ typedef struct {
int logOutputLevel; // log output level
int statistics_requested, use_negotiated_latencies;
enum playback_mode_type playback_mode;
char *cmd_start, *cmd_stop;
char *cmd_start, *cmd_stop, *cmd_set_volume;
int cmd_blocking;
double tolerance; // allow this much drift before attempting to correct it
enum stuffing_type packet_stuffing;
@@ -203,6 +203,7 @@ config_t config_file_stuff;
void command_start(void);
void command_stop(void);
void command_set_volume(double volume);
void shairport_shutdown();
// void shairport_startup_complete(void);
+2
View File
@@ -2109,6 +2109,8 @@ void player_volume(double airplay_volume, rtsp_conn_info* conn) {
// Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate
// it back to a number.
command_set_volume(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
+4
View File
@@ -499,6 +499,10 @@ int parse_options(int argc, char **argv) {
config.volume_max_db_set = 1;
}
if (config_lookup_string(config.cfg, "general.run_this_when_volume_is_set", &str)) {
config.cmd_set_volume = (char *)str;
}
/* Get the playback_mode setting */
if (config_lookup_string(config.cfg, "general.playback_mode", &str)) {
if (strcasecmp(str, "stereo") == 0)