void audio_ls_outputs(void) {
audio_output **out;
- printf("Available audio outputs:\n");
+ printf("Available audio backends:\n");
for (out = outputs; *out; out++)
printf(" %s%s\n", (*out)->name, out == outputs ? " (default)" : "");
for (out = outputs; *out; out++) {
printf("\n");
if ((*out)->help) {
- printf("Options for output %s:\n", (*out)->name);
+ printf("Settings and options for the audio backend \"%s\":\n", (*out)->name);
(*out)->help();
} else {
- printf("No options for output %s:\n", (*out)->name);
+ printf("There are no settings or options for the audio backend \"%s\".\n", (*out)->name);
}
}
}
static int measurement_data_is_valid;
static void help(void) {
- printf(" -d output-device set the output device [default*|...]\n"
- " -m mixer-device set the mixer device ['output-device'*|...]\n"
- " -c mixer-control set the mixer control [Master*|...]\n"
- " -i mixer-index set the mixer index [0*|...]\n"
- " *) default option\n");
+ printf(" -d output-device set the output device, default is \"default\".\n"
+ " -c mixer-control set the mixer control name, default is to use no mixer.\n"
+ " -m mixer-device set the mixer device, default is the output device.\n"
+ " -i mixer-index set the mixer index, default is 0.\n");
}
void set_alsa_out_dev(char *dev) { alsa_out_dev = dev; }
debug(3, "Mixer Control name is \"%s\".", alsa_mix_ctrl);
alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
if (!alsa_mix_elem) {
- debug(1, "Failed to find mixer element");
+ warn("failed to find mixer control \"%s\".", alsa_mix_ctrl);
response = -5;
} else {
response = 1; // we found a hardware mixer and successfully opened it
static void stop(void) { debug(1, "dummy audio stopped\n"); }
-static void help(void) { printf(" There are no options for dummy audio.\n"); }
audio_output audio_dummy = {.name = "dummy",
- .help = &help,
+ .help = NULL,
.init = &init,
.deinit = &deinit,
.start = &start,
pa_stream_disconnect(stream);
}
-static void help(void) { printf(" no settings.\n"); }
-
audio_output audio_pa = {.name = "pa",
- .help = &help,
+ .help = NULL,
.init = &init,
.deinit = &deinit,
.start = &start,
close(fd);
}
-static void help(void) { printf(" pipe takes 1 argument: the name of the FIFO to write to.\n"); }
+static void help(void) { printf(" specify the pathname of the pipe to write to.\n"); }
audio_output audio_pipe = {.name = "pipe",
.help = &help,
// don't close stdout
}
-static void help(void) { printf(" stdout takes no arguments\n"); }
-
audio_output audio_stdout = {.name = "stdout",
- .help = &help,
+ .help = NULL,
.init = &init,
.deinit = &deinit,
.start = &start,
// 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.
- int volume_range_hw_priority; // when lowering the volume, use all the hw attenuation before using
+ int volume_range_hw_priority; // when extending the volume range by combining sw and hw attenuators, lowering the volume, use all the hw attenuation before using
// sw attenuation
enum sps_format_t output_format;
enum volume_control_profile_type volume_control_profile;
// before using the hw attenuation.
// one imagines that hw priority is likely to be much better
// if (config.volume_range_hw_priority) {
- if (1) {
+ if (config.volume_range_hw_priority != 0) {
// hw priority
if ((sw_max_db - sw_min_db) > scaled_attenuation) {
software_attenuation = sw_min_db + scaled_attenuation;
// volume_control_profile = "standard" ; // use this advanced setting to specify how the airplay volume is transferred to the mixer volume.
// "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_range_hw_priority = "yes"; // 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 attenuator first, then the software attenuator.
// 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".
#include "activity_monitor.h"
#include "common.h"
-#include "mdns.h"
#include "rtp.h"
#include "rtsp.h"
#include <FFTConvolver/convolver.h>
#endif
-static int shutting_down = 0;
+// static int shutting_down = 0;
char configuration_file_path[4096 + 1];
char actual_configuration_file_path[4096 + 1];
static void sig_child(__attribute__((unused)) int foo, __attribute__((unused)) siginfo_t *bar,
__attribute__((unused)) void *baz) {
+ // wait for child processes to exit
pid_t pid;
while ((pid = waitpid((pid_t)-1, 0, WNOHANG)) > 0) {
- if (pid == mdns_pid && !shutting_down) {
- die("MDNS child process died unexpectedly!");
- }
}
}
config.fixedLatencyOffset = 11025; // this sounds like it works properly.
config.diagnostic_drop_packet_fraction = 0.0;
config.active_mode_timeout = 10.0;
+ config.volume_range_hw_priority = 1; // if combining software and hardware volume control, give the hardware priority
+ // i.e. when reducing volume, reduce the hw first before reducing the software.
#ifdef CONFIG_METADATA_HUB
config.cover_art_cache_dir = "/tmp/shairport-sync/.cache/coverart";
die("Invalid volume_control_profile choice \"%s\". It should be \"standard\" (default) "
"or \"flat\"");
}
+
+ config_set_lookup_bool(config.cfg, "general.volume_control_combined_hardware_priority", &config.volume_range_hw_priority);
+
/* Get the interface to listen on, if specified Default is all interfaces */
/* we keep the interface name and the index */