[alsa-devel] Question about Conversion to S24_LE from S24_3LE
Hi Takashi,
I am facing similar problem like this issue, hope to get your advice. http://mailman.alsa-project.org/pipermail/alsa-devel/2012-August/054241.html
I try to turn on S24_LE support for HDMI Audio using below patch. When I aplay S24_LE file it works fine. The problem happen when I aplay S24_3LE file, I get and extremely low volume.
When I aplay S24_LE file, I get an left justified value in I2S, this is an expected result: Front end S24_LE : 0x12345600(in 4bytes, LSB 0 padding) Back end S24_3LE : 0x12345600(in 4bytes, LSB 0 padding)
When I aplay S24_3LE file, I get an extremely low output volume. Front end S24_3LE : 0x123456(in 3bytes, No padding) Back end S24_LE : 0x00123456(in 4bytes, MSB 0 padding)
Can you advice how to tell the alsa plugin to pad in LSB instead of MSB?
Below are the patch I used to turn on S24_LE for HDA .
Regards, Seng Kai
From 33f182fe1f6d1e49d0618559d1212b619ec902ce Mon Sep 17 00:00:00 2001
From: "SengKai,Tan" seng.kai.tan@intel.com Date: Fri, 8 Apr 2016 17:34:51 +0800 Subject: [PATCH] ALSA: hda: S24_LE format support for HDA Audio
This patch is to add S24_LE support for HDMI audio and HDA codec.
Before this patch, HDMI and HDA codec audio only supported S16_LE and S32_LE. Let's say if user would like to play S24_LE file, it has to use plugin to convert to either S16_LE or S32_LE which will increase in processing and less efficient in utilize the resources.
On the other side, let's say connected HDMI monitor support S16_LE and S24_LE. Before this patch is applied audio has to be converted to S16_LE. That will reduce the audio quality.
Signed-off-by: Tan, Seng Kai seng.kai.tan@intel.com --- sound/pci/hda/hda_codec.c | 6 ++++-- sound/pci/hda/hda_eld.c | 6 ++++-- sound/pci/hda/patch_hdmi.c | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 57197be..9e737bb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3501,14 +3501,16 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (val & AC_SUPPCM_BITS_32) formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE; if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24)) - formats |= SNDRV_PCM_FMTBIT_S32_LE; + formats |= SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE; if (val & AC_SUPPCM_BITS_24) bps = 24; else if (val & AC_SUPPCM_BITS_20) bps = 20; } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24| AC_SUPPCM_BITS_32)) { - formats |= SNDRV_PCM_FMTBIT_S32_LE; + formats |= SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE; if (val & AC_SUPPCM_BITS_32) bps = 32; else if (val & AC_SUPPCM_BITS_24) diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 0e6d753..65bfe10 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -613,12 +613,14 @@ void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, channels_max = a->channels; if (a->format == AUDIO_CODING_TYPE_LPCM) { if (a->sample_bits & AC_SUPPCM_BITS_20) { - formats |= SNDRV_PCM_FMTBIT_S32_LE; + formats |= SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE; if (maxbps < 20) maxbps = 20; } if (a->sample_bits & AC_SUPPCM_BITS_24) { - formats |= SNDRV_PCM_FMTBIT_S32_LE; + formats |= SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE; if (maxbps < 24) maxbps = 24; } diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d02eccd..8cbde13 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2489,7 +2489,8 @@ static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = { SNDRV_PCM_RATE_192000) #define SUPPORTED_MAXBPS 24 #define SUPPORTED_FORMATS \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) #endif
static int nvhdmi_7x_init_2ch(struct hda_codec *codec)
Tan, Seng Kai wrote:
I am facing similar problem like this issue, hope to get your advice. http://mailman.alsa-project.org/pipermail/alsa-devel/2012-August/054241.html
And the answer is the same.
I try to turn on S24_LE support for HDMI Audio using below patch.
Your hardware does not support S24_LE.
24-bit samples use the S32_LE format (unless you have very exotic hardware, but HDA isn't).
Back end S24_LE : 0x00123456(in 4bytes, MSB 0 padding)
This is how S24_LE works.
Can you advice how to tell the alsa plugin to pad in LSB instead of MSB?
Use S32_LE.
Regards, Clemens
Thanks Clemens
Tan, Seng Kai wrote:
I am facing similar problem like this issue, hope to get your advice. http://mailman.alsa-project.org/pipermail/alsa-devel/2012-August/05424 1.html
And the answer is the same.
I try to turn on S24_LE support for HDMI Audio using below patch.
Your hardware does not support S24_LE. 24-bit samples use the S32_LE format (unless you have very exotic hardware, but HDA isn't).
We have another I2S hardware which is able to support S24L_LE and S32_LE format, when I use -Dplughw to play S24_3LE format the same things happen. It pad the 0 in MSB the whole data is shift to right and the audio volume is lower. Is this the problem for alsa plugins?
Back end S24_LE : 0x00123456(in 4bytes, MSB 0 padding)
This is how S24_LE works.
S24_LE in wav file supposed to be in format 0x00123456 ( 0 pad MSB) or 0x12345600 ( 0 pad LSB) which one is correct? I am a bit confuse here, because When I open file with 0x12345600 ( 0 pad LSB) using audacity, it is able to view the file But not for 0x00123456 ( 0 pad MSB).
Can you advice how to tell the alsa plugin to pad in LSB instead of MSB?
Use S32_LE.
Question: is all HDMI support 24 bit must have 32bit support? My concern is it don't And we want to maximize the quality to 24bit.
Regards, Seng Kai
Tan, Seng Kai wrote:
Your hardware does not support S24_LE. 24-bit samples use the S32_LE format (unless you have very exotic hardware, but HDA isn't).
We have another I2S hardware which is able to support S24L_LE and S32_LE format,
The format on the codec's bus has almost nothing to do with the ALSA sample format.
The Sxx_xE format describes how the samples are formatted in memory, i.e., how the DMA controller expects to read them.
S24_LE in wav file
.wav files do no use ALSA sample formats.
Please describe the values of the header fields in this .wav file.
Question: is all HDMI support 24 bit must have 32bit support?
That depends on the DMA controller. Most use 32-bit alignment for 24-bit samples.
Regards, Clemens
Tan, Seng Kai wrote:
Your hardware does not support S24_LE. 24-bit samples use the S32_LE format (unless you have very exotic hardware, but HDA isn't).
We have another I2S hardware which is able to support S24L_LE and S32_LE format,
The format on the codec's bus has almost nothing to do with the ALSA sample format.
The Sxx_xE format describes how the samples are formatted in memory, i.e., how the DMA controller expects to read them.
I think I get what you mean. The input to the driver should be 0x123456 (3 byte, no padding) And the driver supposed to arrange it to 0x12345600 (4 byte, LSB padding for left justified) That is because the driver do not support and the value get truncate
S24_LE in wav file
.wav files do no use ALSA sample formats.
Please describe the values of the header fields in this .wav file.
qwavheaderdump -F ~/Public/workspace/aud_file/Tones/2ch_48sine_S24_LE.wav /home/ilab/Public/workspace/aud_file/Tones/2ch_48sine_S24_LE.wav (11520044 bytes): riff: 'RIFF' riff length: 11520036 wave: 'WAVE' fmt: 'fmt ' fmt length: 16 format: 1 channels: 2 sample rate: 48000 bytes/second: 384000 bytes/sample: 8 bytes/sample field should be 1, 2 or 4 don't know which value must be set...
bits/sample: 24 data: 'data' data length: 11520000
Regards, Clemens
Tan, Seng Kai wrote:
The input to the driver should be 0x123456 (3 byte, no padding) And the driver supposed to arrange it to 0x12345600 (4 byte, LSB padding for left justified)
No, the kernel driver should never change sample data.
If the hardware supports only 32-bit-aligned samples, then the driver must declare that. Any needed conversions are then done in user space.
S24_LE in wav file
qwavheaderdump -F ~/Public/workspace/aud_file/Tones/2ch_48sine_S24_LE.wav channels: 2 sample rate: 48000 bytes/second: 384000 bytes/sample: 8 bits/sample: 24
This is not correct according to the .wav specification; the wBitsPerSamples field must be the container size, which is 32 here (as shown by nChannels and nBlockAlign).
If the number of valid bits is less than the container size, the file must use the wValidBitsPerSample field in the WAVEFORMATEXTENSIBLE structure.
Anyway, .wav files cannot describe or use S24_LE samples, they use either S32_LE (as in this file) or S24_3LE.
Regards, Clemens
participants (2)
-
Clemens Ladisch
-
Tan, Seng Kai