Make endian-independent. Allow users to specify only U8/S8/S16/S24/S32

This commit is contained in:
Mike Brady
2016-09-12 22:01:57 +01:00
parent 0d45f0b738
commit 0499743bd9
5 changed files with 52 additions and 87 deletions
+29 -12
View File
@@ -204,19 +204,19 @@ static int init(int argc, char **argv) {
/* Get the output format, using the same names as aplay does*/
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;
if (strcasecmp(str, "S16") == 0)
config.output_format = SPS_FORMAT_S16;
else if (strcasecmp(str, "S24") == 0)
config.output_format = SPS_FORMAT_S24;
else if (strcasecmp(str, "S32") == 0)
config.output_format = SPS_FORMAT_S32;
else if (strcasecmp(str, "U8") == 0)
config.output_format = SPS_FORMAT_U8;
else if (strcasecmp(str, "S8") == 0)
config.output_format = SPS_FORMAT_S8;
else
die("Invalid output format \"%s\". It should be \"U8\", \"S8\", \"S16_LE\", \"S24_LE\" or "
"\"S32_LE\"",
die("Invalid output format \"%s\". It should be \"U8\", \"S8\", \"S16\", \"S24\" or "
"\"S32\"",
str);
}
@@ -445,10 +445,27 @@ int open_alsa_device(void) {
die("audio_alsa: Access type not available for device \"%s\": %s", alsa_out_dev,
snd_strerror(ret));
}
ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sample_format);
snd_pcm_format_t sf;
switch (sample_format) {
case SPS_FORMAT_S8:
sf = SND_PCM_FORMAT_S8;
break;
case SPS_FORMAT_U8:
sf = SND_PCM_FORMAT_U8;
break;
case SPS_FORMAT_S16:
sf = SND_PCM_FORMAT_S16;
break;
case SPS_FORMAT_S24:
sf = SND_PCM_FORMAT_S24;
break;
case SPS_FORMAT_S32:
sf = SND_PCM_FORMAT_S32;
break;
}
ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sf);
if (ret < 0) {
die("audio_alsa: Sample format %d not available for device \"%s\": %s", sample_format,
die("audio_alsa: Sample format %d not available for device \"%s\": %s", sf,
alsa_out_dev, snd_strerror(ret));
}
@@ -678,7 +695,7 @@ static void start(int i_sample_rate, int i_sample_format) {
desired_sample_rate = i_sample_rate; // must be a variable
if (i_sample_format == 0)
sample_format = SND_PCM_FORMAT_S16_LE; // default
sample_format = SPS_FORMAT_S16; // default
else
sample_format = i_sample_format;
}
+5 -57
View File
@@ -59,64 +59,12 @@ enum decoders_supported_type {
// the following enum must _exactly match the snd_pcm_format_t definition in the alsa pcm.h file.
enum sps_format_t {
SPS_FORMAT_UNKNOWN = -1,
SPS_FORMAT_S8 = 0,
SPS_FORMAT_UNKNOWN = 0,
SPS_FORMAT_S8,
SPS_FORMAT_U8,
SPS_FORMAT_S16_LE,
SPS_FORMAT_S16_BE,
SPS_FORMAT_U16_LE,
SPS_FORMAT_U16_BE,
SPS_FORMAT_S24_LE,
SPS_FORMAT_S24_BE,
SPS_FORMAT_U24_LE,
SPS_FORMAT_U24_BE,
SPS_FORMAT_S32_LE,
SPS_FORMAT_S32_BE,
SPS_FORMAT_U32_LE,
SPS_FORMAT_U32_BE,
SPS_FORMAT_FLOAT_LE,
SPS_FORMAT_FLOAT_BE,
SPS_FORMAT_FLOAT64_LE,
SPS_FORMAT_FLOAT64_BE,
SPS_FORMAT_IEC958_SUBFRAME_LE,
SPS_FORMAT_IEC958_SUBFRAME_BE,
SPS_FORMAT_MU_LAW,
SPS_FORMAT_A_LAW,
SPS_FORMAT_IMA_ADPCM,
SPS_FORMAT_MPEG,
SPS_FORMAT_GSM,
SPS_FORMAT_SPECIAL = 31,
SPS_FORMAT_S24_3LE = 32,
SPS_FORMAT_S24_3BE,
SPS_FORMAT_U24_3LE,
SPS_FORMAT_U24_3BE,
SPS_FORMAT_S20_3LE,
SPS_FORMAT_S20_3BE,
SPS_FORMAT_U20_3LE,
SPS_FORMAT_U20_3BE,
SPS_FORMAT_S18_3LE,
SPS_FORMAT_S18_3BE,
SPS_FORMAT_U18_3LE,
SPS_FORMAT_U18_3BE,
SPS_FORMAT_G723_24,
SPS_FORMAT_G723_24_1B,
SPS_FORMAT_G723_40,
SPS_FORMAT_G723_40_1B,
SPS_FORMAT_DSD_U8,
SPS_FORMAT_DSD_U16_LE,
SPS_FORMAT_DSD_U32_LE,
SPS_FORMAT_DSD_U16_BE,
SPS_FORMAT_DSD_U32_BE,
SPS_FORMAT_LAST = SPS_FORMAT_DSD_U32_BE,
SPS_FORMAT_S16 = SPS_FORMAT_S16_LE,
SPS_FORMAT_U16 = SPS_FORMAT_U16_LE,
SPS_FORMAT_S24 = SPS_FORMAT_S24_LE,
SPS_FORMAT_U24 = SPS_FORMAT_U24_LE,
SPS_FORMAT_S32 = SPS_FORMAT_S32_LE,
SPS_FORMAT_U32 = SPS_FORMAT_U32_LE,
SPS_FORMAT_FLOAT = SPS_FORMAT_FLOAT_LE,
SPS_FORMAT_FLOAT64 = SPS_FORMAT_FLOAT64_LE,
SPS_FORMAT_IEC958_SUBFRAME = SPS_FORMAT_IEC958_SUBFRAME_LE
SPS_FORMAT_S16,
SPS_FORMAT_S24,
SPS_FORMAT_S32,
} sps_format_t;
typedef struct {
+15 -15
View File
@@ -647,13 +647,13 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
int64_t dither_mask;
switch (format) {
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32:
dither_mask = (int64_t)1 << (64 + 1 - 32);
break;
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24:
dither_mask = (int64_t)1 << (64 + 1 - 24);
break;
case SPS_FORMAT_S16_LE:
case SPS_FORMAT_S16:
dither_mask = (int64_t)1 << (64 + 1 - 16);
break;
case SPS_FORMAT_S8:
@@ -683,29 +683,29 @@ 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;
switch (format) {
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32:
hyper_sample >>= (64 - 32);
*(int32_t *)op = hyper_sample;
result = 4;
break;
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24:
hyper_sample >>= (64 - 24);
*(int32_t *)op = hyper_sample;
result = 4;
break;
case SPS_FORMAT_S16_LE:
case SPS_FORMAT_S16:
hyper_sample >>= (64 - 16);
*(int16_t *)op = hyper_sample;
*(int16_t *)op = (int16_t)hyper_sample;
result = 2;
break;
case SPS_FORMAT_S8:
hyper_sample >>= (64 - 8);
hyper_sample >>= (int8_t)(64 - 8);
*op = hyper_sample;
result = 1;
break;
case SPS_FORMAT_U8:
hyper_sample >>= (64 - 8);
hyper_sample += 128; // this is just a guess!
hyper_sample >>= (uint8_t)(64 - 8);
hyper_sample += 128;
*op = hyper_sample;
result = 1;
break;
@@ -1465,10 +1465,10 @@ static void *player_thread_func(void *arg) {
output_bytes_per_frame = 4;
switch (config.output_format) {
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24:
output_bytes_per_frame = 8;
break;
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32:
output_bytes_per_frame = 8;
break;
}
@@ -1538,13 +1538,13 @@ static void *player_thread_func(void *arg) {
case SPS_FORMAT_U8:
output_bit_depth = 8;
break;
case SPS_FORMAT_S16_LE:
case SPS_FORMAT_S16:
output_bit_depth = 16;
break;
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24:
output_bit_depth = 24;
break;
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32:
output_bit_depth = 32;
break;
}
+1 -1
View File
@@ -61,7 +61,7 @@ alsa =
// mixer_control_name = "PCM"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
// mixer_device = "default"; // the mixer_device default is whatever the output_device is. Normally you wouldn't have to use this.
// output_rate = 44100; // can be 44100, 88200, 176400, 352800, but the device must be capable of it
// output_format = "S16_LE"; // can be "S16_LE", "S24_LE" or "S32_LE", but the device must be capable of it
// output_format = "S16"; // can be "U8", "S8", "S16", "S24" or "S32", with be LE or BE depending on the processor, but the device must be capable of it
// audio_backend_latency_offset = 0.0; // Set this offset in seconds to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -0.1.
// audio_backend_buffer_desired_length = 0.15; // Given in seconds. If set too small, buffer underflow occurs on low-powered machines. Too long and the response times with software mixer become annoying.
// disable_synchronization = "no"; // Set to "yes" to disable synchronization. Default is "no".
+2 -2
View File
@@ -791,7 +791,7 @@ int main(int argc, char **argv) {
config.audio_backend_buffer_desired_length = 6615; // 0.15 seconds.
config.udp_port_base = 6001;
config.udp_port_range = 100;
config.output_format = SPS_FORMAT_S16_LE; // default
config.output_format = SPS_FORMAT_S16; // default
config.output_rate = 44100; // default
config.decoders_supported =
1 << decoder_hammerton; // David Hammerton's decoder supported by default
@@ -1074,7 +1074,7 @@ 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 (0 means 44,100).", config.output_rate);
debug(1, "output_format is %d (2 is the default SPS_FORMAT_S16_LE).", config.output_format);
debug(1, "output_format is %d (3 is the default SPS_FORMAT_S16).", config.output_format);
debug(1, "audio backend desired buffer length is %f seconds.",
config.audio_backend_buffer_desired_length);
debug(1, "audio backend latency offset is %f seconds.", config.audio_backend_latency_offset);