Add *untested* support for S24_3LE and S24_3BE output format.

This commit is contained in:
Mike Brady
2016-09-28 11:47:44 +01:00
parent d0f3b7f3e6
commit b5ee350b3c
4 changed files with 52 additions and 8 deletions
+17 -5
View 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;
+2
View File
@@ -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;
+31 -2
View File
@@ -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:
+2 -1
View 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);