Add ability to set output format and output rate
This commit is contained in:
@@ -19,7 +19,7 @@ typedef struct {
|
||||
// at end of program
|
||||
void (*deinit)(void);
|
||||
|
||||
void (*start)(int sample_rate);
|
||||
void (*start)(int sample_rate, int sample_format);
|
||||
|
||||
// block of samples
|
||||
void (*play)(short buf[], int samples);
|
||||
|
||||
+45
-9
@@ -38,7 +38,7 @@
|
||||
static void help(void);
|
||||
static int init(int argc, char **argv);
|
||||
static void deinit(void);
|
||||
static void start(int sample_rate);
|
||||
static void start(int i_sample_rate, int i_sample_format);
|
||||
static void play(short buf[], int samples);
|
||||
static void stop(void);
|
||||
static void flush(void);
|
||||
@@ -68,6 +68,7 @@ audio_output audio_alsa = {
|
||||
static pthread_mutex_t alsa_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static unsigned int desired_sample_rate;
|
||||
static snd_pcm_format_t sample_format;
|
||||
|
||||
static snd_pcm_t *alsa_handle = NULL;
|
||||
static snd_pcm_hw_params_t *alsa_params = NULL;
|
||||
@@ -205,6 +206,35 @@ static int init(int argc, char **argv) {
|
||||
die("Invalid disable_synchronization option choice \"%s\". It should be \"yes\" or \"no\"");
|
||||
}
|
||||
|
||||
/* Get the output format, using the same names as aplay does -- S16_LE, S32_LE to begin with*/
|
||||
if (config_lookup_string(config.cfg, "alsa.output_format", &str)) {
|
||||
if (strcasecmp(str, "S16_LE") == 0)
|
||||
config.output_format = SND_PCM_FORMAT_S16_LE;
|
||||
else if (strcasecmp(str, "S24_LE") == 0)
|
||||
config.output_format = SND_PCM_FORMAT_S24_LE;
|
||||
else if (strcasecmp(str, "S32_LE") == 0)
|
||||
config.output_format = SND_PCM_FORMAT_S32_LE;
|
||||
else
|
||||
die("Invalid output format \"%s\". It should be \"S16_LE\", \"S24_LE\" or \"S32_LE\"",str);
|
||||
}
|
||||
|
||||
/* Get the output rate, which must be a multiple of 44,100*/
|
||||
if (config_lookup_int(config.cfg, "alsa.output_rate",
|
||||
&value)) {
|
||||
debug(1,"Value read for output rate is %d.",value);
|
||||
switch(value) {
|
||||
case 44100:
|
||||
case 88200:
|
||||
case 176400:
|
||||
case 352800:
|
||||
config.output_rate = value;
|
||||
break;
|
||||
default :
|
||||
die("Invalid output rate \"%d\". It should be a multiple of 44,100 up to 352,800",value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get the use_mmap_if_available setting. */
|
||||
if (config_lookup_string(config.cfg, "alsa.use_mmap_if_available", &str)) {
|
||||
if (strcasecmp(str, "no") == 0)
|
||||
@@ -424,11 +454,10 @@ int open_alsa_device(void) {
|
||||
alsa_out_dev, snd_strerror(ret));
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params,
|
||||
SND_PCM_FORMAT_S16);
|
||||
ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sample_format);
|
||||
if (ret < 0) {
|
||||
die("audio_alsa: Sample format not available for device \"%s\": %s",
|
||||
alsa_out_dev, snd_strerror(ret));
|
||||
die("audio_alsa: Sample format %d not available for device \"%s\": %s",
|
||||
sample_format, alsa_out_dev, snd_strerror(ret));
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_channels(alsa_handle, alsa_params, 2);
|
||||
@@ -640,11 +669,18 @@ int open_alsa_device(void) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void start(int sample_rate) {
|
||||
static void start(int i_sample_rate, int i_sample_format) {
|
||||
// debug(2,"audio_alsa start called.");
|
||||
if (sample_rate != 44100)
|
||||
die("Unexpected sample rate %d -- only 44,100 supported!", sample_rate);
|
||||
desired_sample_rate = sample_rate; // must be a variable
|
||||
if (i_sample_rate==0)
|
||||
desired_sample_rate = 44100; // default
|
||||
else
|
||||
desired_sample_rate = i_sample_rate; // must be a variable
|
||||
|
||||
if (i_sample_format==0)
|
||||
sample_format = SND_PCM_FORMAT_S16_LE; // default
|
||||
else
|
||||
sample_format = i_sample_format;
|
||||
|
||||
}
|
||||
|
||||
int delay(long* the_delay) {
|
||||
|
||||
+4
-2
@@ -134,9 +134,11 @@ static void deinit(void) {
|
||||
ao_shutdown();
|
||||
}
|
||||
|
||||
static void start(int sample_rate) {
|
||||
if (sample_rate != 44100)
|
||||
static void start(int sample_rate, int sample_format) {
|
||||
if (sample_rate != 0)
|
||||
die("unexpected sample rate!");
|
||||
if (sample_format != 0)
|
||||
die("unexpected sample format!");
|
||||
}
|
||||
|
||||
static void play(short buf[], int samples) { ao_play(dev, (char *)buf, samples * 4); }
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ static int init(int argc, char **argv) { return 0; }
|
||||
|
||||
static void deinit(void) {}
|
||||
|
||||
static void start(int sample_rate) {
|
||||
static void start(int sample_rate, int sample_format) {
|
||||
Fs = sample_rate;
|
||||
starttime = 0;
|
||||
samples_played = 0;
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ static int fd = -1;
|
||||
|
||||
char *pipename = NULL;
|
||||
|
||||
static void start(int sample_rate) {
|
||||
static void start(int sample_rate, int sample_format) {
|
||||
// this will leave fd as -1 if a reader hasn't been attached
|
||||
fd = open(pipename, O_WRONLY | O_NONBLOCK);
|
||||
}
|
||||
|
||||
+4
-2
@@ -110,9 +110,11 @@ static void deinit(void) {
|
||||
pa_dev = NULL;
|
||||
}
|
||||
|
||||
static void start(int sample_rate) {
|
||||
if (sample_rate != 44100)
|
||||
static void start(int sample_rate, int sample_format) {
|
||||
if (sample_rate != 0)
|
||||
die("unexpected sample rate!");
|
||||
if (sample_format != 0)
|
||||
die("unexpected sample format!");
|
||||
}
|
||||
|
||||
static void play(short buf[], int samples) {
|
||||
|
||||
@@ -56,6 +56,8 @@ static void deinit(void) { sio_close(sio); }
|
||||
static void start(int sample_rate) {
|
||||
if (sample_rate != par.rate)
|
||||
die("unexpected sample rate!");
|
||||
if (sample_format != 0)
|
||||
die("unexpected sample format!");
|
||||
sio_start(sio);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
|
||||
static int fd = -1;
|
||||
|
||||
static void start(int sample_rate) {
|
||||
static void start(int sample_rate int sample_format) {
|
||||
fd = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ typedef struct {
|
||||
// audio backend buffer -- the DAC buffer for ALSA
|
||||
long audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency there might be in the audio path
|
||||
uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's native range.
|
||||
int output_format;
|
||||
int output_rate;
|
||||
} shairport_cfg;
|
||||
|
||||
// true if Shairport Sync is supposed to be sending output to the output device, false otherwise
|
||||
|
||||
@@ -1716,7 +1716,7 @@ int player_play(stream_cfg *stream, pthread_t *player_thread) {
|
||||
#endif
|
||||
if (rc)
|
||||
debug(1, "Error initialising condition variable.");
|
||||
config.output->start(sampling_rate);
|
||||
config.output->start(config.output_rate,config.output_format);
|
||||
size_t size = (PTHREAD_STACK_MIN + 256 * 1024);
|
||||
pthread_attr_t tattr;
|
||||
pthread_attr_init(&tattr);
|
||||
|
||||
@@ -1016,6 +1016,8 @@ int main(int argc, char **argv) {
|
||||
debug(1, "playback_mode is %d (0-stereo, 1-mono).", config.playback_mode);
|
||||
debug(1, "disable_synchronization is %d.", config.no_sync);
|
||||
debug(1, "use_mmap_if_available is %d.", config.no_mmap ? 0 : 1);
|
||||
debug(1, "output_rate is %d (0 means 44,100).", config.output_rate);
|
||||
debug(1, "output_format is %d (0 means S16_LE).", config.output_format);
|
||||
debug(1, "audio backend desired buffer length is %d.",
|
||||
config.audio_backend_buffer_desired_length);
|
||||
debug(1, "audio backend latency offset is %d.", config.audio_backend_latency_offset);
|
||||
|
||||
Reference in New Issue
Block a user