Make the play function return a status (ignored for the present). Clean up audio_alsa by removing all the die calls and placing the alsa_mutex calls in pthread cleanup routines.

This commit is contained in:
Mike Brady
2018-07-29 13:45:42 +01:00
parent c91a991edd
commit ea20840d6c
11 changed files with 207 additions and 169 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ typedef struct {
void (*start)(int sample_rate, int sample_format);
// block of samples
void (*play)(void *buf, int samples);
int (*play)(void *buf, int samples);
void (*stop)(void);
// may be null if not implemented
+182 -160
View File
@@ -41,7 +41,7 @@ static void help(void);
static int init(int argc, char **argv);
static void deinit(void);
static void start(int i_sample_rate, int i_sample_format);
static void play(void *buf, int samples);
static int play(void *buf, int samples);
static void stop(void);
static void flush(void);
int delay(long *the_delay);
@@ -134,6 +134,7 @@ static void help(void) {
void set_alsa_out_dev(char *dev) { alsa_out_dev = dev; }
int open_mixer() {
int response = 0;
if (hardware_mixer) {
debug(3, "Open Mixer");
int ret = 0;
@@ -141,25 +142,38 @@ int open_mixer() {
snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_ctrl);
if ((snd_mixer_open(&alsa_mix_handle, 0)) < 0)
die("Failed to open mixer");
debug(3, "Mixer device name is \"%s\".", alsa_mix_dev);
if ((snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0)
die("Failed to attach mixer");
if ((snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0)
die("Failed to register mixer element");
ret = snd_mixer_load(alsa_mix_handle);
if (ret < 0)
die("Failed to load mixer element");
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)
die("Failed to find mixer element");
return 1;
} else {
return 0;
}
if ((snd_mixer_open(&alsa_mix_handle, 0)) < 0) {
debug(1,"Failed to open mixer");
response = -1;
} else {
debug(3, "Mixer device name is \"%s\".", alsa_mix_dev);
if ((snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0) {
debug(1,"Failed to attach mixer");
response = -2;
} else {
if ((snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0) {
debug(1,"Failed to register mixer element");
response = -3;
} else {
ret = snd_mixer_load(alsa_mix_handle);
if (ret < 0) {
debug(1,"Failed to load mixer element");
response = -4;
} else {
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");
response = -5;
} else {
response = 1; // we found a hardware mixer and successfully opened it
}
}
}
}
}
}
return response;
}
void close_mixer() {
@@ -179,8 +193,8 @@ void do_snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *mix_elem, double v
}
static int init(int argc, char **argv) {
debug_mutex_lock(&alsa_mutex, 1000, 1);
// debug(2,"audio_alsa init called.");
int response = 0; // this will be what we return to the caller.
const char *str;
int value;
// double dvalue;
@@ -232,8 +246,8 @@ static int init(int argc, char **argv) {
else if (strcasecmp(str, "yes") == 0)
config.no_sync = 1;
else {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid disable_synchronization option choice \"%s\". It should be \"yes\" or \"no\"");
warn("Invalid disable_synchronization option choice \"%s\". It should be \"yes\" or \"no\". It is set to \"no\".");
config.no_sync = 0;
}
}
@@ -246,9 +260,9 @@ static int init(int argc, char **argv) {
else if (strcasecmp(str, "yes") == 0)
config.alsa_use_hardware_mute = 1;
else {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid mute_using_playback_switch option choice \"%s\". It should be \"yes\" or "
"\"no\"");
warn("Invalid mute_using_playback_switch option choice \"%s\". It should be \"yes\" or "
"\"no\". It is set to \"no\".");
config.alsa_use_hardware_mute = 0;
}
}
@@ -259,9 +273,9 @@ static int init(int argc, char **argv) {
else if (strcasecmp(str, "yes") == 0)
config.alsa_use_hardware_mute = 1;
else {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid use_hardware_mute_if_available option choice \"%s\". It should be \"yes\" or "
"\"no\"");
warn("Invalid use_hardware_mute_if_available option choice \"%s\". It should be \"yes\" or "
"\"no\". It is set to \"no\".");
config.alsa_use_hardware_mute = 0;
}
}
@@ -282,11 +296,11 @@ static int init(int argc, char **argv) {
else if (strcasecmp(str, "S8") == 0)
config.output_format = SPS_FORMAT_S8;
else {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid output format \"%s\". It should be \"U8\", \"S8\", \"S16\", \"S24\", "
warn("Invalid output format \"%s\". It should be \"U8\", \"S8\", \"S16\", \"S24\", "
"\"S24_3LE\", \"S24_3BE\" or "
"\"S32\"",
"\"S32\". It is set to \"S16\".",
str);
config.output_format = SPS_FORMAT_S16;
}
}
@@ -301,8 +315,8 @@ static int init(int argc, char **argv) {
config.output_rate = value;
break;
default:
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid output rate \"%d\". It should be a multiple of 44,100 up to 352,800", value);
warn("Invalid output rate \"%d\". It should be a multiple of 44,100 up to 352,800. It is set to 44,100", value);
config.output_rate = 44100;
}
}
@@ -313,8 +327,8 @@ static int init(int argc, char **argv) {
else if (strcasecmp(str, "yes") == 0)
config.no_mmap = 0;
else {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid use_mmap_if_available option choice \"%s\". It should be \"yes\" or \"no\"");
warn("Invalid use_mmap_if_available option choice \"%s\". It should be \"yes\" or \"no\". It is set to \"yes\".");
config.no_mmap = 0;
}
}
/* Get the optional period size value */
@@ -322,10 +336,10 @@ static int init(int argc, char **argv) {
set_period_size_request = 1;
debug(1, "Value read for period size is %d.", value);
if (value < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid alsa period size setting \"%d\". It "
"must be greater than 0.",
warn("Invalid alsa period size setting \"%d\". It "
"must be greater than 0. No setting is made.",
value);
set_period_size_request = 0;
} else {
period_size_requested = value;
}
@@ -336,10 +350,10 @@ static int init(int argc, char **argv) {
set_buffer_size_request = 1;
debug(1, "Value read for buffer size is %d.", value);
if (value < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid alsa buffer size setting \"%d\". It "
"must be greater than 0.",
warn("Invalid alsa buffer size setting \"%d\". It "
"must be greater than 0. No setting is made.",
value);
set_buffer_size_request = 0;
} else {
buffer_size_requested = value;
}
@@ -374,15 +388,13 @@ static int init(int argc, char **argv) {
alsa_mix_index = strtol(optarg, NULL, 10);
break;
default:
warn("Invalid audio option \"-%c\" specified -- ignored.", opt);
help();
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid audio option -%c specified", opt);
}
}
if (optind < argc) {
debug_mutex_unlock(&alsa_mutex, 3);
die("Invalid audio argument: %s", argv[optind]);
warn("Invalid audio argument: \"%s\" -- ignored", argv[optind]);
}
debug(1, "alsa output device name is \"%s\".", alsa_out_dev);
@@ -392,92 +404,93 @@ static int init(int argc, char **argv) {
if (alsa_mix_dev == NULL)
alsa_mix_dev = alsa_out_dev;
// Open mixer
// Now, start trying to initialise the alsa device with the settings obtained
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 1000, 1);
if (open_mixer()==1) {
if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) <
0)
debug(1, "Can't read mixer's [linear] min and max volumes.");
else {
if (snd_mixer_selem_get_playback_dB_range(alsa_mix_elem, &alsa_mix_mindb, &alsa_mix_maxdb) ==
0) {
open_mixer();
if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) <
0)
debug(1, "Can't read mixer's [linear] min and max volumes.");
else {
if (snd_mixer_selem_get_playback_dB_range(alsa_mix_elem, &alsa_mix_mindb, &alsa_mix_maxdb) ==
0) {
audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
audio_alsa.parameters = &parameters; // likewise the parameters stuff
if (alsa_mix_mindb == SND_CTL_TLV_DB_GAIN_MUTE) {
// 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?
// 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)
debug(1, "Can't get dB value corresponding to a minimum volume + 1.");
}
debug(1, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
(1.0 * alsa_mix_maxdb) / 100.0);
} else {
// use the linear scale and do the db conversion ourselves
debug(1,
"note: the hardware mixer specified -- \"%s\" -- does not have "
"a dB volume scale.",
alsa_mix_ctrl);
if (snd_ctl_open(&ctl, alsa_mix_dev, 0) < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("Cannot open control \"%s\"", alsa_mix_dev);
}
if (snd_ctl_elem_id_malloc(&elem_id) < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("Cannot allocate memory for control \"%s\"", alsa_mix_dev);
}
snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(elem_id, alsa_mix_ctrl);
if (snd_ctl_get_dB_range(ctl, elem_id, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {
debug(1, "Volume control \"%s\" has dB volume from %f to %f.", alsa_mix_ctrl,
(1.0 * alsa_mix_mindb) / 100.0, (1.0 * alsa_mix_maxdb) / 100.0);
has_softvol = 1;
audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
audio_alsa.parameters = &parameters; // likewise the parameters stuff
if (alsa_mix_mindb == SND_CTL_TLV_DB_GAIN_MUTE) {
// 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?
// 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)
debug(1, "Can't get dB value corresponding to a minimum volume + 1.");
}
debug(1, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
(1.0 * alsa_mix_maxdb) / 100.0);
} else {
debug(1, "Cannot get the dB range from the volume control \"%s\"", alsa_mix_ctrl);
}
// use the linear scale and do the db conversion ourselves
warn("The hardware mixer specified -- \"%s\" -- does not have "
"a dB volume scale.",
alsa_mix_ctrl);
/*
debug(1, "Min and max volumes are %d and
%d.",alsa_mix_minv,alsa_mix_maxv);
alsa_mix_maxdb = 0;
if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
alsa_mix_mindb =
-20*100*(log10(alsa_mix_maxv*1.0)-log10(alsa_mix_minv*1.0));
else if (alsa_mix_maxv!=0)
alsa_mix_mindb = -20*100*log10(alsa_mix_maxv*1.0);
audio_alsa.volume = &linear_volume; // insert the linear volume function
audio_alsa.parameters = &parameters; // likewise the parameters stuff
debug(1,"Max and min dB calculated are %d and
%d.",alsa_mix_maxdb,alsa_mix_mindb);
*/
if (snd_ctl_open(&ctl, alsa_mix_dev, 0) < 0) {
warn("Cannot open control \"%s\"", alsa_mix_dev);
response = -1;
}
if (snd_ctl_elem_id_malloc(&elem_id) < 0) {
debug(1,"Cannot allocate memory for control \"%s\"", alsa_mix_dev);
elem_id = NULL;
response = -2;
} else {
snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(elem_id, alsa_mix_ctrl);
if (snd_ctl_get_dB_range(ctl, elem_id, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {
debug(1, "Volume control \"%s\" has dB volume from %f to %f.", alsa_mix_ctrl,
(1.0 * alsa_mix_mindb) / 100.0, (1.0 * alsa_mix_maxdb) / 100.0);
has_softvol = 1;
audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
audio_alsa.parameters = &parameters; // likewise the parameters stuff
} else {
debug(1, "Cannot get the dB range from the volume control \"%s\"", alsa_mix_ctrl);
}
}
/*
debug(1, "Min and max volumes are %d and
%d.",alsa_mix_minv,alsa_mix_maxv);
alsa_mix_maxdb = 0;
if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
alsa_mix_mindb =
-20*100*(log10(alsa_mix_maxv*1.0)-log10(alsa_mix_minv*1.0));
else if (alsa_mix_maxv!=0)
alsa_mix_mindb = -20*100*log10(alsa_mix_maxv*1.0);
audio_alsa.volume = &linear_volume; // insert the linear volume function
audio_alsa.parameters = &parameters; // likewise the parameters stuff
debug(1,"Max and min dB calculated are %d and
%d.",alsa_mix_maxdb,alsa_mix_mindb);
*/
}
}
if (((config.alsa_use_hardware_mute == 1) &&
(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 {
// debug(1, "Has mixer but not using hardware mute.");
}
close_mixer();
}
if (((config.alsa_use_hardware_mute == 1) &&
(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 {
// debug(1, "Has mixer but not using hardware mute.");
}
close_mixer();
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
} else {
// debug(1, "Has no mixer and thus no hardware mute.");
}
alsa_mix_handle = NULL;
debug_mutex_unlock(&alsa_mutex, 3);
return 0;
return response;
}
static void deinit(void) {
@@ -487,7 +500,6 @@ static void deinit(void) {
int open_alsa_device(void) {
// the alsa mutex is already acquired when this is called
const snd_pcm_uframes_t minimal_buffer_headroom =
352 * 2; // we accept this much headroom in the hardware buffer, but we'll
// accept less
@@ -515,17 +527,16 @@ int open_alsa_device(void) {
ret = snd_pcm_open(&alsa_handle, alsa_out_dev, SND_PCM_STREAM_PLAYBACK, 0);
if (ret < 0)
return (ret);
return (-10);
snd_pcm_hw_params_alloca(&alsa_params);
ret = snd_pcm_hw_params_any(alsa_handle, alsa_params);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
;
die("audio_alsa: Broken configuration for device \"%s\": no configurations "
warn("audio_alsa: Broken configuration for device \"%s\": no configurations "
"available",
alsa_out_dev);
return -11;
}
if ((config.no_mmap == 0) &&
@@ -548,9 +559,9 @@ int open_alsa_device(void) {
ret = snd_pcm_hw_params_set_access(alsa_handle, alsa_params, access);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: Access type not available for device \"%s\": %s", alsa_out_dev,
warn("audio_alsa: Access type not available for device \"%s\": %s", alsa_out_dev,
snd_strerror(ret));
return -12;
}
snd_pcm_format_t sf;
switch (sample_format) {
@@ -576,28 +587,29 @@ int open_alsa_device(void) {
sf = SND_PCM_FORMAT_S32;
break;
default:
debug_mutex_unlock(&alsa_mutex, 3);
sf = SND_PCM_FORMAT_S16; // this is just to quieten a compiler warning
die("Unsupported output format at audio_alsa.c");
debug(1,"Unsupported output format at audio_alsa.c");
return -1;
}
ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sf);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: Sample format %d not available for device \"%s\": %s", sample_format,
warn("audio_alsa: Sample format %d not available for device \"%s\": %s", sample_format,
alsa_out_dev, snd_strerror(ret));
return -2;
}
ret = snd_pcm_hw_params_set_channels(alsa_handle, alsa_params, 2);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: Channels count (2) not available for device \"%s\": %s", alsa_out_dev,
warn("audio_alsa: Channels count (2) not available for device \"%s\": %s", alsa_out_dev,
snd_strerror(ret));
return -3;
}
ret = snd_pcm_hw_params_set_rate_near(alsa_handle, alsa_params, &my_sample_rate, &dir);
if (ret < 0) {
die("audio_alsa: Rate %iHz not available for playback: %s", desired_sample_rate,
warn("audio_alsa: Rate %iHz not available for playback: %s", desired_sample_rate,
snd_strerror(ret));
return -4;
}
if (set_period_size_request != 0) {
@@ -605,9 +617,10 @@ int open_alsa_device(void) {
ret = snd_pcm_hw_params_set_period_size_near(alsa_handle, alsa_params, &period_size_requested,
&dir);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: cannot set period size of %lu: %s", period_size_requested,
warn("audio_alsa: cannot set period size of %lu: %s", period_size_requested,
snd_strerror(ret));
return -5;
} else {
snd_pcm_uframes_t actual_period_size;
snd_pcm_hw_params_get_period_size(alsa_params, &actual_period_size, &dir);
if (actual_period_size != period_size_requested)
@@ -621,35 +634,36 @@ int open_alsa_device(void) {
debug(1, "Attempting to set the buffer size to %lu", buffer_size_requested);
ret = snd_pcm_hw_params_set_buffer_size_near(alsa_handle, alsa_params, &buffer_size_requested);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: cannot set buffer size of %lu: %s", buffer_size_requested,
warn("audio_alsa: cannot set buffer size of %lu: %s", buffer_size_requested,
snd_strerror(ret));
return -6;
} else {
snd_pcm_uframes_t actual_buffer_size;
snd_pcm_hw_params_get_buffer_size(alsa_params, &actual_buffer_size);
if (actual_buffer_size != buffer_size_requested)
inform("Actual period size set to a different value than requested. Requested: %lu, actual "
"setting: %lu",
buffer_size_requested, actual_buffer_size);
}
snd_pcm_uframes_t actual_buffer_size;
snd_pcm_hw_params_get_buffer_size(alsa_params, &actual_buffer_size);
if (actual_buffer_size != buffer_size_requested)
inform("Actual period size set to a different value than requested. Requested: %lu, actual "
"setting: %lu",
buffer_size_requested, actual_buffer_size);
}
ret = snd_pcm_hw_params(alsa_handle, alsa_params);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: Unable to set hw parameters for device \"%s\": %s.", alsa_out_dev,
warn("audio_alsa: Unable to set hw parameters for device \"%s\": %s.", alsa_out_dev,
snd_strerror(ret));
return -7;
}
if (my_sample_rate != desired_sample_rate) {
debug_mutex_unlock(&alsa_mutex, 3);
die("Can't set the D/A converter to %d.", desired_sample_rate);
warn("Can't set the D/A converter to %d.", desired_sample_rate);
return -8;
}
ret = snd_pcm_hw_params_get_buffer_size(alsa_params, &actual_buffer_length);
if (ret < 0) {
debug_mutex_unlock(&alsa_mutex, 3);
die("audio_alsa: Unable to get hw buffer length for device \"%s\": %s.", alsa_out_dev,
warn("audio_alsa: Unable to get hw buffer length for device \"%s\": %s.", alsa_out_dev,
snd_strerror(ret));
return -9;
}
if (actual_buffer_length < config.audio_backend_buffer_desired_length + minimal_buffer_headroom) {
@@ -809,7 +823,7 @@ int open_alsa_device(void) {
}
}
return (0);
return 0;
}
static void start(int i_sample_rate, int i_sample_format) {
@@ -835,7 +849,7 @@ int delay(long *the_delay) {
if (alsa_handle == NULL) {
return -ENODEV;
} else {
debug_mutex_lock(&alsa_mutex, 10000, 1);
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
int derr;
if (snd_pcm_state(alsa_handle) == SND_PCM_STATE_RUNNING) {
*the_delay = 0; // just to see what happens
@@ -867,6 +881,7 @@ int delay(long *the_delay) {
}
}
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0);
// here, occasionally pretend there's a problem with pcm_get_delay()
// if ((random() % 100000) < 3) // keep it pretty rare
// reply = -EPERM; // pretend something bad has happened
@@ -885,11 +900,11 @@ int get_rate_information(uint64_t *elapsed_time, uint64_t *frames_played) {
return 0;
}
static void play(void *buf, int samples) {
static int play(void *buf, int samples) {
// debug(3,"audio_alsa play called.");
int ret = 0;
if (alsa_handle == NULL) {
debug_mutex_lock(&alsa_mutex, 10000, 1);
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
ret = open_alsa_device();
if (ret == 0) {
if (audio_alsa.volume)
@@ -897,10 +912,12 @@ static void play(void *buf, int samples) {
if (audio_alsa.mute)
do_mute(0);
}
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
}
if (ret == 0) {
debug_mutex_lock(&alsa_mutex, 10000, 1);
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
// snd_pcm_sframes_t current_delay = 0;
int err, err2;
if (snd_pcm_state(alsa_handle) == SND_PCM_STATE_XRUN) {
@@ -965,12 +982,14 @@ static void play(void *buf, int samples) {
measurement_data_is_valid = 0;
}
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
}
return ret;
}
static void flush(void) {
// debug(2,"audio_alsa flush called.");
debug_mutex_lock(&alsa_mutex, 10000, 1);
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
int derr;
do_mute(1);
@@ -990,6 +1009,7 @@ static void flush(void) {
alsa_handle = NULL;
}
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
}
static void stop(void) {
@@ -1010,7 +1030,7 @@ static void parameters(audio_parameters *info) {
void do_volume(double vol) { // caller is assumed to have the alsa_mutex when using this function
debug(3, "Setting volume db to %f.", vol);
set_volume = vol;
if (volume_set_request && open_mixer()) {
if (volume_set_request && (open_mixer()==1)) {
if (has_softvol) {
if (ctl && elem_id) {
snd_ctl_elem_value_t *value;
@@ -1042,10 +1062,11 @@ void do_volume(double vol) { // caller is assumed to have the alsa_mutex when us
}
void volume(double vol) {
debug_mutex_lock(&alsa_mutex, 1000, 1);
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 1000, 1);
volume_set_request = 1; // an external request has been made to set the volume
do_volume(vol);
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
}
/*
@@ -1068,11 +1089,12 @@ static void linear_volume(double vol) {
static void mute(int mute_state_requested) {
// debug(1,"External Mute Request: %d",mute_state_requested);
debug_mutex_lock(&alsa_mutex, 10000, 1);
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
mute_request_pending = 1;
overriding_mute_state_requested = mute_state_requested;
do_mute(mute_state_requested);
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
}
void do_mute(int mute_state_requested) {
@@ -1093,7 +1115,7 @@ void do_mute(int mute_state_requested) {
if (config.alsa_use_hardware_mute == 1) {
if (mute_request_pending == 0)
local_mute_state_requested = mute_state_requested;
if (open_mixer()) {
if (open_mixer()==1) {
if (local_mute_state_requested) {
// debug(1,"Playback Switch mute actually done");
if (snd_mixer_selem_has_playback_switch(alsa_mix_elem))
+3 -1
View File
@@ -121,7 +121,9 @@ static void deinit(void) {
static void start(__attribute__((unused)) int sample_rate,
__attribute__((unused)) int sample_format) {}
static void play(void *buf, int samples) { ao_play(dev, buf, samples * 4); }
static int play(void *buf, int samples) {
return ao_play(dev, buf, samples * 4);
}
static void stop(void) {}
+1 -1
View File
@@ -48,7 +48,7 @@ static void start(int sample_rate, __attribute__((unused)) int sample_format) {
debug(1, "dummy audio output started at Fs=%d Hz\n", sample_rate);
}
static void play(__attribute__((unused)) void *buf, __attribute__((unused)) int samples) {}
static int play(__attribute__((unused)) void *buf, __attribute__((unused)) int samples) { return 0; }
static void stop(void) { debug(1, "dummy audio stopped\n"); }
+2 -1
View File
@@ -198,7 +198,7 @@ static void start(__attribute__((unused)) int sample_rate,
pa_threaded_mainloop_unlock(mainloop);
}
static void play(void *buf, int samples) {
static int play(void *buf, int samples) {
// debug(1,"pa_play of %d samples.",samples);
// copy the samples into the queue
size_t bytes_to_transfer = samples * 2 * 2;
@@ -224,6 +224,7 @@ static void play(void *buf, int samples) {
pa_stream_cork(stream, 0, stream_success_cb, mainloop);
pa_threaded_mainloop_unlock(mainloop);
}
return 0;
}
int pa_delay(long *the_delay) {
+2 -1
View File
@@ -54,7 +54,7 @@ static void start(__attribute__((unused)) int sample_rate,
}
}
static void play(void *buf, int samples) {
static int play(void *buf, int samples) {
// if the file is not open, try to open it.
char errorstring[1024];
if (fd == -1) {
@@ -73,6 +73,7 @@ static void play(void *buf, int samples) {
warn("Error %d opening the pipe named \"%s\": \"%s\".", errno, pipename, errorstring);
warned = 1;
}
return warned;
}
static void stop(void) {
+3 -2
View File
@@ -33,7 +33,7 @@ static int init(int, char **);
static void onmove_cb(void *, int);
static void deinit(void);
static void start(int, int);
static void play(void *, int);
static int play(void *, int);
static void stop(void);
static void onmove_cb(void *, int);
static int delay(long *);
@@ -222,12 +222,13 @@ static void start(__attribute__((unused)) int sample_rate,
pthread_mutex_unlock(&sndio_mutex);
}
static void play(void *buf, int frames) {
static int play(void *buf, int frames) {
if (frames > 0) {
pthread_mutex_lock(&sndio_mutex);
written += sio_write(hdl, buf, frames * framesize);
pthread_mutex_unlock(&sndio_mutex);
}
return 0;
}
static void stop() {
+2 -1
View File
@@ -168,7 +168,7 @@ static void start(int sample_rate, int sample_format) {
debug(1, "libsoundio output started\n");
}
static void play(void *buf, int samples) {
static int play(void *buf, int samples) {
// int err;
int free_bytes = soundio_ring_buffer_free_count(ring_buffer);
int written_bytes = 0;
@@ -187,6 +187,7 @@ static void play(void *buf, int samples) {
soundio_ring_buffer_advance_write_ptr(ring_buffer, write_bytes);
debug(3, "[<<---] Written to buffer : %d\n", written_bytes);
}
return 0;
}
static void parameters(audio_parameters *info) {
+2 -1
View File
@@ -43,7 +43,7 @@ static void start(__attribute__((unused)) int sample_rate,
fd = STDOUT_FILENO;
}
static void play(void *buf, int samples) {
static int play(void *buf, int samples) {
char errorstring[1024];
int warned = 0;
int rc = write(fd, buf, samples * 4);
@@ -52,6 +52,7 @@ static void play(void *buf, int samples) {
warn("Error %d writing to stdout: \"%s\".", errno, errorstring);
warned = 1;
}
return rc;
}
static void stop(void) {
+4
View File
@@ -1141,6 +1141,10 @@ int _debug_mutex_unlock(pthread_mutex_t *mutex, const char *filename, const int
return r;
}
void pthread_cleanup_debug_mutex_unlock(void *arg) {
pthread_mutex_unlock((pthread_mutex_t* )arg);
}
char *get_version_string() {
char *version_string = malloc(200);
if (version_string) {
+5
View File
@@ -298,6 +298,11 @@ int _debug_mutex_unlock(pthread_mutex_t *mutex, const char *filename, const int
#define debug_mutex_unlock(mu, d) _debug_mutex_unlock(mu, __FILE__, __LINE__, d)
void pthread_cleanup_debug_mutex_unlock(void *arg);
#define pthread_cleanup_debug_mutex_lock(mu, t, d) if (_debug_mutex_lock(mu, t, __FILE__, __LINE__, d) == 0) pthread_cleanup_push(pthread_cleanup_debug_mutex_unlock,(void *)mu)
char *get_version_string(); // mallocs a string space -- remember to free it afterwards
void sps_nanosleep(const time_t sec,