/* 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);
}
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));
}
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;
}
// 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 {
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:
// 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;
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;
}
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;
}
// 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".
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
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);