Skip to content

Commit

Permalink
pretty-print after adding alsa volume-based mute capability
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebrady committed Jan 13, 2018
1 parent 6d792fa commit e0aa75a
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 76 deletions.
23 changes: 14 additions & 9 deletions audio_alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@ static int has_softvol = 0;
static int volume_set_request = 0; // set when an external request is made to set the volume.
int mute_request_pending = 0; // set when an external request is made to mute or unmute.
int overriding_mute_state_requested = 0; // 1 = mute; 0 = unmute requested
int mixer_volume_setting_gives_mute = 0; // set when it is discovered that particular mixer volume setting causes a mute.
long alsa_mix_mute; // setting the volume to this value mutes output, if mixer_volume_setting_gives_mute is true
int volume_based_mute_is_active = 0; // set when muting is being done by a setting the volume to a magic value
int mixer_volume_setting_gives_mute =
0; // set when it is discovered that particular mixer volume setting causes a mute.
long alsa_mix_mute; // setting the volume to this value mutes output, if
// mixer_volume_setting_gives_mute is true
int volume_based_mute_is_active =
0; // set when muting is being done by a setting the volume to a magic value

static snd_pcm_sframes_t (*alsa_pcm_write)(snd_pcm_t *, const void *,
snd_pcm_uframes_t) = snd_pcm_writei;
Expand Down Expand Up @@ -152,7 +155,7 @@ void close_mixer() {
}
}

void do_snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t * mix_elem, double vol) {
void do_snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *mix_elem, double vol) {
if (snd_mixer_selem_set_playback_dB_all(mix_elem, vol, 0) != 0) {
debug(1, "Can't set playback volume accurately to %f dB.", vol);
if (snd_mixer_selem_set_playback_dB_all(mix_elem, vol, -1) != 0)
Expand Down Expand Up @@ -377,7 +380,8 @@ static int init(int argc, char **argv) {
// For instance, the Raspberry Pi does this
debug(1, "Lowest dB value is a mute");
mixer_volume_setting_gives_mute = 1;
alsa_mix_mute = SND_CTL_TLV_DB_GAIN_MUTE; // this may not be necessary -- it's always going to be SND_CTL_TLV_DB_GAIN_MUTE, right?
alsa_mix_mute = SND_CTL_TLV_DB_GAIN_MUTE; // this may not be necessary -- it's always
// going to be SND_CTL_TLV_DB_GAIN_MUTE, right?
// debug(1, "Try minimum volume + 1 as lowest true attenuation value");
if (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv + 1,
&alsa_mix_mindb) != 0)
Expand Down Expand Up @@ -429,7 +433,8 @@ static int init(int argc, char **argv) {
}
}
if ((config.alsa_use_playback_switch_for_mute == 1) &&
(snd_mixer_selem_has_playback_switch(alsa_mix_elem)) || mixer_volume_setting_gives_mute) {
(snd_mixer_selem_has_playback_switch(alsa_mix_elem)) ||
mixer_volume_setting_gives_mute) {
audio_alsa.mute = &mute; // insert the mute function now we know it can do muting stuff
// debug(1, "Has mixer and mute ability we will use.");
} else {
Expand Down Expand Up @@ -961,11 +966,11 @@ void do_volume(double vol) { // caller is assumed to have the alsa_mutex when us
"control.");
}
} else {
if (volume_based_mute_is_active==0) {
if (volume_based_mute_is_active == 0) {
// debug(1,"Set alsa volume.");
do_snd_mixer_selem_set_playback_dB_all(alsa_mix_elem, vol);
} else {
debug(1,"Not setting volume because volume-based mute is active");
debug(1, "Not setting volume because volume-based mute is active");
}
}
volume_set_request = 0; // any external request that has been made is now satisfied
Expand Down Expand Up @@ -1022,7 +1027,7 @@ void do_mute(int mute_state_requested) {
// If the hardware isn't there, or we are not allowed to use it, nothing will be done
// The caller must have the alsa mutex

if ((config.alsa_use_playback_switch_for_mute == 1) || mixer_volume_setting_gives_mute){
if ((config.alsa_use_playback_switch_for_mute == 1) || mixer_volume_setting_gives_mute) {
if (mute_request_pending == 0)
local_mute_state_requested = mute_state_requested;
if (open_mixer()) {
Expand Down
5 changes: 3 additions & 2 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ typedef struct {
mdns_backend *mdns;
int buffer_start_fill;
int64_t userSuppliedLatency; // overrides all other latencies -- use with caution
int64_t fixedLatencyOffset; // add this to all automatic latencies supplied to get the actual total latency
// the total latency will be limited to the min and max-latency values, if supplied
int64_t fixedLatencyOffset; // add this to all automatic latencies supplied to get the actual
// total latency
// the total latency will be limited to the min and max-latency values, if supplied
int daemonise;
int daemonise_store_pid; // don't try to save a PID file
char *piddir;
Expand Down
14 changes: 6 additions & 8 deletions dacp.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ int32_t dacp_get_client_volume(void) {
int32_t item_size;
if (reply_size >= 8) {
if (dacp_tlv_crawl(&sp, &item_size) == 'cmgt') {
debug(1,"Volume:",item_size);
debug(1, "Volume:", item_size);
sp -= item_size; // drop down into the array -- don't skip over it
reply_size -= 8;
while (reply_size >= 8) {
Expand All @@ -627,12 +627,12 @@ int32_t dacp_get_client_volume(void) {
}
}
} else {
debug(1,"Unexpected payload response from getproperty?properties=dmcp.volume");
debug(1, "Unexpected payload response from getproperty?properties=dmcp.volume");
}
} else {
debug(1,"Too short a response from getproperty?properties=dmcp.volume");
debug(1, "Too short a response from getproperty?properties=dmcp.volume");
}
debug(1,"Overall Volume is %d.",overall_volume);
debug(1, "Overall Volume is %d.", overall_volume);
free(server_reply);
} else {
debug(1, "Unexpected response %d to dacp volume control request", response);
Expand All @@ -658,8 +658,7 @@ int dacp_set_speaker_volume(int64_t machine_number, int32_t vo) {
// should return 204
}

int dacp_get_speaker_list(dacp_spkr_stuff *speaker_info,
int max_size_of_array) {
int dacp_get_speaker_list(dacp_spkr_stuff *speaker_info, int max_size_of_array) {
char *server_reply = NULL;
int speaker_index = -1; // will be incremented before use
int reply = -1; // will bve fixed if there is no problem
Expand Down Expand Up @@ -775,7 +774,7 @@ void dacp_get_volume(void) {
// calculate the real volume

int32_t overall_volume = dacp_get_client_volume();
debug(1,"DACP Volume: %d.",overall_volume);
debug(1, "DACP Volume: %d.", overall_volume);
int speaker_count = dacp_get_speaker_list((dacp_spkr_stuff *)&speaker_info, 50);
// debug(1,"DACP Speaker Count: %d.",speaker_count);

Expand Down Expand Up @@ -804,4 +803,3 @@ void dacp_get_volume(void) {
run_metadata_watchers();
}
}

6 changes: 3 additions & 3 deletions dacp.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ uint32_t dacp_tlv_crawl(

int dacp_set_speaker_volume(int64_t machine_number, int32_t vo);

int dacp_get_speaker_list(dacp_spkr_stuff *speaker_array,
int max_size_of_array);
int dacp_get_speaker_list(dacp_spkr_stuff *speaker_array, int max_size_of_array);
void set_dacp_server_information(rtsp_conn_info *conn); // tell the DACP conversation thread that
// the dacp server information has been set
// or changed
int send_simple_dacp_command(const char *command);

void dacp_get_volume(void); // get the speaker volume information from the DACP source and store it in the metadata_hub
void dacp_get_volume(void); // get the speaker volume information from the DACP source and store it
// in the metadata_hub
14 changes: 8 additions & 6 deletions metadata_hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,16 @@ typedef struct metadata_bundle {

unsigned char
item_composite_id[16]; // seems to be nowplaying 4 ids: dbid, plid, playlistItem, itemid

//

enum play_status_type player_state; // this is the state of the actual player itself, which can be a bit noisy.

int speaker_volume; // this is the actual speaker volume, allowing for the main volume and the speaker volume control

enum play_status_type
player_state; // this is the state of the actual player itself, which can be a bit noisy.

int speaker_volume; // this is the actual speaker volume, allowing for the main volume and the
// speaker volume control
int previous_speaker_volume; // this is needed to prevent a loop

metadata_watcher watchers[number_of_watchers]; // functions to call if the metadata is changed.
void *watchers_data[number_of_watchers]; // their individual data

Expand Down
28 changes: 14 additions & 14 deletions player.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,10 +816,10 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {

// say we have started playing here
#ifdef HAVE_METADATA_HUB
if (metadata_store.player_state != PS_PLAYING) {
metadata_store.player_state = PS_PLAYING;
run_metadata_watchers();
}
if (metadata_store.player_state != PS_PLAYING) {
metadata_store.player_state = PS_PLAYING;
run_metadata_watchers();
}
#endif
if (reference_timestamp) { // if we have a reference time
// debug(1,"First frame seen with timestamp...");
Expand Down Expand Up @@ -1366,9 +1366,10 @@ static void *player_thread_func(void *arg) {
conn->first_packet_timestamp = 0;
conn->flush_requested = 0;
// conn->fix_volume = 0x10000;

if (conn->latency==0) {
debug(1,"No latency has (yet) been specified. Setting 99225 (2.25 seconds) frames as a default.");

if (conn->latency == 0) {
debug(1,
"No latency has (yet) been specified. Setting 99225 (2.25 seconds) frames as a default.");
conn->latency = 99225;
}

Expand Down Expand Up @@ -2500,9 +2501,8 @@ void player_flush(int64_t timestamp, rtsp_conn_info *conn) {
if (metadata_store.player_state != PS_PAUSED) {
metadata_store.player_state = PS_PAUSED;
run_metadata_watchers();
}
}
#endif

}

int player_play(rtsp_conn_info *conn) {
Expand Down Expand Up @@ -2532,7 +2532,7 @@ int player_play(rtsp_conn_info *conn) {
if (metadata_store.player_state != PS_PLAYING) {
metadata_store.player_state = PS_PLAYING;
run_metadata_watchers();
}
}
#endif
return 0;
}
Expand All @@ -2550,10 +2550,10 @@ void player_stop(rtsp_conn_info *conn) {
free(conn->player_thread);
conn->player_thread = NULL;
#ifdef HAVE_METADATA_HUB
if (metadata_store.player_state != PS_STOPPED) {
metadata_store.player_state = PS_STOPPED;
run_metadata_watchers();
}
if (metadata_store.player_state != PS_STOPPED) {
metadata_store.player_state = PS_STOPPED;
run_metadata_watchers();
}
#endif
} else {
debug(3, "player thread of RTSP conversation %d is already deleted.", conn->connection_number);
Expand Down
12 changes: 7 additions & 5 deletions player.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ typedef struct {
} stream_cfg;

typedef struct {
int connection_number; // for debug ID purposes, nothing else...
int64_t latency; // the actual latency used for this play session
int64_t minimum_latency; // set if an a=min-latency: line appears in the ANNOUNCE message; zero otherwise
int64_t maximum_latency; // set if an a=max-latency: line appears in the ANNOUNCE message; zero otherwise

int connection_number; // for debug ID purposes, nothing else...
int64_t latency; // the actual latency used for this play session
int64_t minimum_latency; // set if an a=min-latency: line appears in the ANNOUNCE message; zero
// otherwise
int64_t maximum_latency; // set if an a=max-latency: line appears in the ANNOUNCE message; zero
// otherwise

int fd;
int authorized; // set if a password is required and has been supplied
stream_cfg stream;
Expand Down
27 changes: 15 additions & 12 deletions rtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,25 +224,28 @@ void *rtp_control_receiver(void *arg) {
// debug(1,"Remote Sync Time: %0llx.",remote_time_of_sync);

sync_rtp_timestamp = monotonic_timestamp(ntohl(*((uint32_t *)&packet[16])), conn);

if (config.userSuppliedLatency) {
if (config.userSuppliedLatency != conn->latency) {
debug(1,"Using the user-supplied latency: %lld.",config.userSuppliedLatency);
debug(1, "Using the user-supplied latency: %lld.", config.userSuppliedLatency);
}
conn->latency = config.userSuppliedLatency;
} else if (packet[0] & 0x10) { // only set latency if it's a packet just after a flush or resume
int64_t rtp_timestamp_less_latency = monotonic_timestamp(ntohl(*((uint32_t *)&packet[4])), conn);
int64_t la =
sync_rtp_timestamp - rtp_timestamp_less_latency + config.fixedLatencyOffset;
if ((conn->maximum_latency) && (conn->maximum_latency<la))
} else if (packet[0] &
0x10) { // only set latency if it's a packet just after a flush or resume
int64_t rtp_timestamp_less_latency =
monotonic_timestamp(ntohl(*((uint32_t *)&packet[4])), conn);
int64_t la = sync_rtp_timestamp - rtp_timestamp_less_latency + config.fixedLatencyOffset;
if ((conn->maximum_latency) && (conn->maximum_latency < la))
la = conn->maximum_latency;
if ((conn->minimum_latency) && (conn->minimum_latency>la))
la = conn->minimum_latency;
if ((conn->minimum_latency) && (conn->minimum_latency > la))
la = conn->minimum_latency;

if (la != conn->latency) {
conn->latency = la;
debug(1,"New latency: %lld, sync latency: %lld, minimum latency: %lld, maximum latency: %lld, fixed offset: %lld.",
la,sync_rtp_timestamp - rtp_timestamp_less_latency,conn->minimum_latency,conn->maximum_latency,config.fixedLatencyOffset);
debug(1, "New latency: %lld, sync latency: %lld, minimum latency: %lld, maximum "
"latency: %lld, fixed offset: %lld.",
la, sync_rtp_timestamp - rtp_timestamp_less_latency, conn->minimum_latency,
conn->maximum_latency, config.fixedLatencyOffset);
}
}

Expand Down
12 changes: 6 additions & 6 deletions rtsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
send_metadata('ssnc', 'daid', ar, strlen(ar), req, 1);
#endif
}

char *hdr = msg_get_header(req, "Transport");
if (!hdr)
goto error;
Expand Down Expand Up @@ -1197,7 +1197,7 @@ void *metadata_thread_function(void *ignore) {
pc_queue_get_item(&metadata_queue, &pack);
if (config.metadata_enabled)
metadata_process(pack.type, pack.code, pack.data, pack.length);

if (pack.carrier)
msg_free(pack.carrier); // release the message
else if (pack.data)
Expand Down Expand Up @@ -1473,18 +1473,18 @@ static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag

if (!strncmp(cp, "a=max-latency:", 14))
pmaxlatency = cp + 14;

cp = next;
}

if (pminlatency) {
conn->minimum_latency = atoi(pminlatency);
debug(1,"Minimum latency %d specified",conn->minimum_latency);
debug(1, "Minimum latency %d specified", conn->minimum_latency);
}

if (pmaxlatency) {
conn->maximum_latency = atoi(pmaxlatency);
debug(1,"Maximum latency %d specified",conn->maximum_latency);
debug(1, "Maximum latency %d specified", conn->maximum_latency);
}

if ((paesiv == NULL) && (prsaaeskey == NULL)) {
Expand Down
26 changes: 15 additions & 11 deletions shairport.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
#include "dacp.h"
#endif


#if defined(HAVE_METADATA_HUB)
#include "metadata_hub.h"
#endif
Expand Down Expand Up @@ -396,16 +395,19 @@ int parse_options(int argc, char **argv) {
inform("Warning: the option -R or --reconnectToOutput is deprecated.");
break;
case 'A':
inform("Warning: the option -A or --AirPlayLatency is deprecated and ignored. This setting is now "
inform("Warning: the option -A or --AirPlayLatency is deprecated and ignored. This setting "
"is now "
"automatically received from the AirPlay device.");
break;
case 'i':
inform("Warning: the option -i or --iTunesLatency is deprecated and ignored. This setting is now "
inform("Warning: the option -i or --iTunesLatency is deprecated and ignored. This setting is "
"now "
"automatically received from iTunes");
break;
case 'f':
inform("Warning: the option --forkedDaapdLatency is deprecated and ignored. This setting is now "
"automatically received from forkedDaapd");
inform(
"Warning: the option --forkedDaapdLatency is deprecated and ignored. This setting is now "
"automatically received from forkedDaapd");
break;
case 'r':
inform("Warning: the option -r or --resync is deprecated. Please use the "
Expand Down Expand Up @@ -1108,9 +1110,9 @@ int main(int argc, char **argv) {
strcat(configuration_file_path, ".conf");
config.configfile = configuration_file_path;

//config.statistics_requested = 0; // don't print stats in the log
//config.userSuppliedLatency = 0; // zero means none supplied
config.resyncthreshold = 0.05; // 50 ms
// config.statistics_requested = 0; // don't print stats in the log
// config.userSuppliedLatency = 0; // zero means none supplied
config.resyncthreshold = 0.05; // 50 ms
config.timeout = 120; // this number of seconds to wait for [more] audio before switching to idle.
config.tolerance =
0.002; // this number of seconds of timing error before attempting to correct it.
Expand Down Expand Up @@ -1341,9 +1343,11 @@ int main(int argc, char **argv) {
}

/* Mess around with the latency options */
// Basically, we expect the source to set the latency and add a fixed offset of 11025 frames to it, which sounds right
// If this latency is outside the max and min latensies that may be set by the source, clamp it to fit.

// Basically, we expect the source to set the latency and add a fixed offset of 11025 frames to
// it, which sounds right
// If this latency is outside the max and min latensies that may be set by the source, clamp it to
// fit.

// If they specify a non-standard latency, we suggest the user to use the
// audio_backend_latency_offset instead.

Expand Down

0 comments on commit e0aa75a

Please sign in to comment.