]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add *untested* support for S24_3LE and S24_3BE output format.
authorMike Brady <mikebrady@eircom.net>
Wed, 28 Sep 2016 10:47:44 +0000 (11:47 +0100)
committerMike Brady <mikebrady@eircom.net>
Wed, 28 Sep 2016 10:47:44 +0000 (11:47 +0100)
audio_alsa.c
common.h
player.c
shairport.c

index 3ebe464246ca03dbe7afcdb869f5b16fb32931be..99b70cd3da228d005744892dfb403271eeb21b17 100644 (file)
@@ -219,6 +219,10 @@ static int init(int argc, char **argv) {
         config.output_format = SPS_FORMAT_S16;
       else if (strcasecmp(str, "S24") == 0)
         config.output_format = SPS_FORMAT_S24;
+      else if (strcasecmp(str, "S24_3LE") == 0)
+        config.output_format = SPS_FORMAT_S24_3LE;
+      else if (strcasecmp(str, "S24_3BE") == 0)
+        config.output_format = SPS_FORMAT_S24_3BE;
       else if (strcasecmp(str, "S32") == 0)
         config.output_format = SPS_FORMAT_S32;
       else if (strcasecmp(str, "U8") == 0)
@@ -226,7 +230,8 @@ static int init(int argc, char **argv) {
       else if (strcasecmp(str, "S8") == 0)
         config.output_format = SPS_FORMAT_S8;
       else
-        die("Invalid output format \"%s\". It should be \"U8\", \"S8\", \"S16\", \"S24\" or "
+        die("Invalid output format \"%s\". It should be \"U8\", \"S8\", \"S16\", \"S24\", "
+            "\"S24_3LE\", \"S24_3BE\" or "
             "\"S32\"",
             str);
     }
@@ -417,10 +422,11 @@ int open_alsa_device(void) {
   // snd_pcm_uframes_t frames = 441 * 10;
   snd_pcm_uframes_t buffer_size, actual_buffer_length;
   snd_pcm_access_t access;
-  
-  // ensure no calls are made to the alsa device enquiring about the buffer length if synchronisation is disabled.
-  if (config.no_sync!=0)
-       audio_alsa.delay = NULL;
+
+  // ensure no calls are made to the alsa device enquiring about the buffer length if
+  // synchronisation is disabled.
+  if (config.no_sync != 0)
+    audio_alsa.delay = NULL;
 
   // ensure no calls are made to the alsa device enquiring about the buffer length if
   // synchronisation is disabled.
@@ -479,6 +485,12 @@ int open_alsa_device(void) {
   case SPS_FORMAT_S24:
     sf = SND_PCM_FORMAT_S24;
     break;
+  case SPS_FORMAT_S24_3LE:
+    sf = SND_PCM_FORMAT_S24_3LE;
+    break;
+  case SPS_FORMAT_S24_3BE:
+    sf = SND_PCM_FORMAT_S24_3BE;
+    break;
   case SPS_FORMAT_S32:
     sf = SND_PCM_FORMAT_S32;
     break;
index 536f24c53c3962b526cb96f9bff89903a3ee8eec..e52f82d29069c28277ed9b6dcaea121af2b68adb 100644 (file)
--- a/common.h
+++ b/common.h
@@ -64,6 +64,8 @@ enum sps_format_t {
   SPS_FORMAT_U8,
   SPS_FORMAT_S16,
   SPS_FORMAT_S24,
+  SPS_FORMAT_S24_3LE,
+  SPS_FORMAT_S24_3BE,
   SPS_FORMAT_S32,
 } sps_format_t;
 
index b5a8d28d7512210e10077fc5a467c41fce8434cc..c09ec67c36397db52f82a99449e85d64ee2859fe 100644 (file)
--- a/player.c
+++ b/player.c
@@ -651,6 +651,8 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
       dither_mask = (int64_t)1 << (64 + 1 - 32);
       break;
     case SPS_FORMAT_S24:
+    case SPS_FORMAT_S24_3LE:
+    case SPS_FORMAT_S24_3BE:
       dither_mask = (int64_t)1 << (64 + 1 - 24);
       break;
     case SPS_FORMAT_S16:
@@ -682,12 +684,33 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
 
   // move the result to the desired position in the int64_t
   char *op = *outp;
+  uint8_t byt;
   switch (format) {
   case SPS_FORMAT_S32:
     hyper_sample >>= (64 - 32);
     *(int32_t *)op = hyper_sample;
     result = 4;
     break;
+  case SPS_FORMAT_S24_3LE:
+    hyper_sample >>= (64 - 24);
+    byt = (uint8_t)hyper_sample;
+    *op++ = byt;
+    byt = (uint8_t)(hyper_sample >> 8);
+    *op++ = byt;
+    byt = (uint8_t)(hyper_sample >> 16);
+    *op++ = byt;
+    result = 3;
+    break;
+  case SPS_FORMAT_S24_3BE:
+    hyper_sample >>= (64 - 24);
+    byt = (uint8_t)(hyper_sample >> 16);
+    *op++ = byt;
+    byt = (uint8_t)(hyper_sample >> 8);
+    *op++ = byt;
+    byt = (uint8_t)hyper_sample;
+    *op++ = byt;
+    result = 3;
+    break;
   case SPS_FORMAT_S24:
     hyper_sample >>= (64 - 24);
     *(int32_t *)op = hyper_sample;
@@ -1174,7 +1197,7 @@ static inline int32_t mean_32(int32_t a, int32_t b) {
 // (b) multiplies each sample by the fixedvolume (a 16-bit quantity)
 // (c) dithers the result to the output size 32/24/16 bits
 // (d) outputs the result in the approprate format
-// formats accepted so far include U8, S8, S16_LE, S24_LE and S32_LE on a little endian machine.
+// formats accepted so far include U8, S8, S16, S24, S24_3LE, S24_3BE and S32
 
 // stuff: 1 means add 1; 0 means do nothing; -1 means remove 1
 static int stuff_buffer_basic_32(int32_t *inptr, int length, enum sps_format_t l_output_format,
@@ -1282,7 +1305,7 @@ static int stuff_buffer_basic(short *inptr, int length, short *outptr, int stuff
 // (b) multiplies each sample by the fixedvolume (a 16-bit quantity)
 // (c) dithers the result to the output size 32/24/16 bits
 // (d) outputs the result in the approprate format
-// formats accepted so far include U8, S8, S16_LE, S24_LE and S32_LE on a little endian machine.
+// formats accepted so far include U8, S8, S16, S24, S24_3LE, S24_3BE and S32
 
 static int stuff_buffer_soxr_32(int32_t *inptr, int32_t *scratchBuffer, int length,
                                 enum sps_format_t l_output_format, char *outptr, int stuff,
@@ -1465,6 +1488,10 @@ static void *player_thread_func(void *arg) {
 
   output_bytes_per_frame = 4;
   switch (config.output_format) {
+  case SPS_FORMAT_S24_3LE:
+  case SPS_FORMAT_S24_3BE:
+    output_bytes_per_frame = 6;
+    break;
   case SPS_FORMAT_S24:
     output_bytes_per_frame = 8;
     break;
@@ -1542,6 +1569,8 @@ static void *player_thread_func(void *arg) {
     output_bit_depth = 16;
     break;
   case SPS_FORMAT_S24:
+  case SPS_FORMAT_S24_3LE:
+  case SPS_FORMAT_S24_3BE:
     output_bit_depth = 24;
     break;
   case SPS_FORMAT_S32:
index 1406de66ba2a5055781e8fad9ffea3923609df52..fd2cd965931c0eee733f7d1a430dfb1bcc1b5511 100644 (file)
@@ -1092,7 +1092,8 @@ int main(int argc, char **argv) {
   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.", config.output_rate);
-  debug(1, "output_format is %d (0-unknown, 1-S8, 2-U8, 3-S16, 4-S24, 5-S32).",
+  debug(1,
+        "output_format is %d (0-unknown, 1-S8, 2-U8, 3-S16, 4-S24, 5-S24_3LE, 6-S24_3BE, 7-S32).",
         config.output_format);
   debug(1, "audio backend desired buffer length is %f seconds.",
         config.audio_backend_buffer_desired_length);