]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add ability to set output format and output rate
authorMike Brady <mikebrady@eircom.net>
Fri, 19 Aug 2016 11:51:15 +0000 (12:51 +0100)
committerMike Brady <mikebrady@eircom.net>
Fri, 19 Aug 2016 11:51:15 +0000 (12:51 +0100)
audio.h
audio_alsa.c
audio_ao.c
audio_dummy.c
audio_pipe.c
audio_pulse.c
audio_sndio.c
audio_stdout.c
common.h
player.c
shairport.c

diff --git a/audio.h b/audio.h
index 4c86d7dba238159e8c62b6ae03db5e1cd26fad30..b93e48b52c79ff1053bffc9a39737dd6a9bb471c 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -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);
index ad5b0c741a7289045c6359db2224e2be81b2de00..db864f651d3e28b117d1f435bf4ce6df3af61cc5 100644 (file)
@@ -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) {
index 41b823b07ac1d5bcd7e57380bf1a584241d08e0e..b6a09a0716e6e0c7cce17816dddc752774656d45 100644 (file)
@@ -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); }
index 659a7202fd6d6a4d6355bf6d59f60a846d93c24e..3f24dadd9e91fff757a91a014cc659a668098321 100644 (file)
@@ -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;
index 17bf310398857226c11643a7f6f04a29c24309fa..dfde2a92e8d291dcd297da7123d330d8a2bcd7be 100644 (file)
@@ -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);
 }
index 6fa94e971c30d7a1d0abbe3c9fe7639c140599fa..e4118259a288a90fba00085dc35be3537c1a9d99 100644 (file)
@@ -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) {
index 7093261ee7e0cdc241911a5ca035f6c26c6a5728..1d2e1532297166124a3b2a6df4cd917a3ba42c5f 100644 (file)
@@ -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);
 }
 
index b8b0aa536160fd505ae56cda995eb4ed38c5e7fd..61b8e6b1c0b9fd73913678ac4810c347546748c3 100644 (file)
@@ -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;
 }
 
index 32ee301d188da78a03d84ee2ddfaaa6dbb6e6be2..625108b06098be063cf7576a873ee1dc8179853f 100644 (file)
--- a/common.h
+++ b/common.h
@@ -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
index 97eccfb2931bb7db3ce74b8a4d2000feb131a12b..3b86a373adaf3de6ba003c3cdf6c6cd1bd689c1c 100644 (file)
--- a/player.c
+++ b/player.c
@@ -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);
index f725d607f4b82249fa3331aaee44861ccbf6f460..1b97099b9c92c05718086710478dd32ba6f4df01 100644 (file)
@@ -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);