Support wrong-endian ALSA output
This commit is contained in:
parent
05693e2d5d
commit
49ede85827
|
@ -183,6 +183,19 @@ get_bitformat(const struct audio_format *af)
|
||||||
return SND_PCM_FORMAT_UNKNOWN;
|
return SND_PCM_FORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static snd_pcm_format_t
|
||||||
|
byteswap_bitformat(snd_pcm_format_t fmt)
|
||||||
|
{
|
||||||
|
switch(fmt) {
|
||||||
|
case SND_PCM_FORMAT_S16_LE: return SND_PCM_FORMAT_S16_BE;
|
||||||
|
case SND_PCM_FORMAT_S24_LE: return SND_PCM_FORMAT_S24_BE;
|
||||||
|
case SND_PCM_FORMAT_S32_LE: return SND_PCM_FORMAT_S32_BE;
|
||||||
|
case SND_PCM_FORMAT_S16_BE: return SND_PCM_FORMAT_S16_LE;
|
||||||
|
case SND_PCM_FORMAT_S24_BE: return SND_PCM_FORMAT_S24_LE;
|
||||||
|
case SND_PCM_FORMAT_S32_BE: return SND_PCM_FORMAT_S32_LE;
|
||||||
|
default: return SND_PCM_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Set up the snd_pcm_t object which was opened by the caller. Set up
|
* Set up the snd_pcm_t object which was opened by the caller. Set up
|
||||||
* the configured settings and the audio format.
|
* the configured settings and the audio format.
|
||||||
|
@ -208,7 +221,6 @@ alsa_setup(struct alsa_data *ad, struct audio_format *audio_format,
|
||||||
configure_hw:
|
configure_hw:
|
||||||
/* configure HW params */
|
/* configure HW params */
|
||||||
snd_pcm_hw_params_alloca(&hwparams);
|
snd_pcm_hw_params_alloca(&hwparams);
|
||||||
|
|
||||||
cmd = "snd_pcm_hw_params_any";
|
cmd = "snd_pcm_hw_params_any";
|
||||||
err = snd_pcm_hw_params_any(ad->pcm, hwparams);
|
err = snd_pcm_hw_params_any(ad->pcm, hwparams);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -236,13 +248,38 @@ configure_hw:
|
||||||
}
|
}
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams, bitformat);
|
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams, bitformat);
|
||||||
|
if (err == -EINVAL &&
|
||||||
|
byteswap_bitformat(bitformat) != SND_PCM_FORMAT_UNKNOWN) {
|
||||||
|
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams,
|
||||||
|
byteswap_bitformat(bitformat));
|
||||||
|
if (err == 0) {
|
||||||
|
g_debug("ALSA device \"%s\": converting %u bit to reverse-endian\n",
|
||||||
|
alsa_device(ad), audio_format->bits);
|
||||||
|
audio_format->reverse_endian = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (err == -EINVAL && (audio_format->bits == 24 ||
|
if (err == -EINVAL && (audio_format->bits == 24 ||
|
||||||
audio_format->bits == 16)) {
|
audio_format->bits == 16)) {
|
||||||
/* fall back to 32 bit, let pcm_convert.c do the conversion */
|
/* fall back to 32 bit, let pcm_convert.c do the conversion */
|
||||||
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams,
|
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams,
|
||||||
SND_PCM_FORMAT_S32);
|
SND_PCM_FORMAT_S32);
|
||||||
if (err == 0)
|
if (err == 0) {
|
||||||
|
g_debug("ALSA device \"%s\": converting %u bit to 32 bit\n",
|
||||||
|
alsa_device(ad), audio_format->bits);
|
||||||
audio_format->bits = 32;
|
audio_format->bits = 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == -EINVAL && (audio_format->bits == 24 ||
|
||||||
|
audio_format->bits == 16)) {
|
||||||
|
/* fall back to 32 bit, let pcm_convert.c do the conversion */
|
||||||
|
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams,
|
||||||
|
byteswap_bitformat(SND_PCM_FORMAT_S32));
|
||||||
|
if (err == 0) {
|
||||||
|
g_debug("ALSA device \"%s\": converting %u bit to 32 bit backward-endian\n",
|
||||||
|
alsa_device(ad), audio_format->bits);
|
||||||
|
audio_format->bits = 32;
|
||||||
|
audio_format->reverse_endian = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == -EINVAL && audio_format->bits != 16) {
|
if (err == -EINVAL && audio_format->bits != 16) {
|
||||||
|
@ -255,6 +292,17 @@ configure_hw:
|
||||||
audio_format->bits = 16;
|
audio_format->bits = 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (err == -EINVAL && audio_format->bits != 16) {
|
||||||
|
/* fall back to 16 bit, let pcm_convert.c do the conversion */
|
||||||
|
err = snd_pcm_hw_params_set_format(ad->pcm, hwparams,
|
||||||
|
byteswap_bitformat(SND_PCM_FORMAT_S16));
|
||||||
|
if (err == 0) {
|
||||||
|
g_debug("ALSA device \"%s\": converting %u bit to 16 bit backward-endian\n",
|
||||||
|
alsa_device(ad), audio_format->bits);
|
||||||
|
audio_format->bits = 16;
|
||||||
|
audio_format->reverse_endian = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
g_set_error(error, alsa_output_quark(), err,
|
g_set_error(error, alsa_output_quark(), err,
|
||||||
|
|
Loading…
Reference in New Issue