All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pcm: softvol: add support for S24_LE
@ 2017-09-08 10:11 Jörg Krause
  2017-09-08 10:52 ` Clemens Ladisch
  0 siblings, 1 reply; 10+ messages in thread
From: Jörg Krause @ 2017-09-08 10:11 UTC (permalink / raw)
  To: alsa-devel; +Cc: Jörg Krause

Tested with a Wolfson WM8524 DAC on a i.MX6UL board running Linux version
4.13.0-next-20170907.

Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
---
 src/pcm/pcm_softvol.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c
index 1fe5784d..d159fb1f 100644
--- a/src/pcm/pcm_softvol.c
+++ b/src/pcm/pcm_softvol.c
@@ -309,6 +309,8 @@ static void softvol_convert_stereo_vol(snd_pcm_softvol_t *svol,
 		CONVERT_AREA(short, 
 			     !snd_pcm_format_cpu_endian(svol->sformat));
 		break;
+	case SND_PCM_FORMAT_S24_LE:
+		/* 24bit samples, fallthrough */
 	case SND_PCM_FORMAT_S32_LE:
 	case SND_PCM_FORMAT_S32_BE:
 		/* 32bit samples */
@@ -360,6 +362,8 @@ static void softvol_convert_mono_vol(snd_pcm_softvol_t *svol,
 		CONVERT_AREA(short, 
 			     !snd_pcm_format_cpu_endian(svol->sformat));
 		break;
+	case SND_PCM_FORMAT_S24_LE:
+		/* 24bit samples, fallthrough */
 	case SND_PCM_FORMAT_S32_LE:
 	case SND_PCM_FORMAT_S32_BE:
 		/* 32bit samples */
@@ -422,6 +426,7 @@ static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm,
 		{
 			(1ULL << SND_PCM_FORMAT_S16_LE) |
 			(1ULL << SND_PCM_FORMAT_S16_BE) |
+			(1ULL << SND_PCM_FORMAT_S24_LE) |
 			(1ULL << SND_PCM_FORMAT_S32_LE) |
  			(1ULL << SND_PCM_FORMAT_S32_BE),
 			(1ULL << (SND_PCM_FORMAT_S24_3LE - 32))
@@ -577,10 +582,11 @@ static int snd_pcm_softvol_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * param
 	if (slave->format != SND_PCM_FORMAT_S16_LE &&
 	    slave->format != SND_PCM_FORMAT_S16_BE &&
 	    slave->format != SND_PCM_FORMAT_S24_3LE && 
+	    slave->format != SND_PCM_FORMAT_S24_LE &&
 	    slave->format != SND_PCM_FORMAT_S32_LE &&
 	    slave->format != SND_PCM_FORMAT_S32_BE) {
-		SNDERR("softvol supports only S16_LE, S16_BE, S24_3LE, S32_LE "
-		       " or S32_BE");
+		SNDERR("softvol supports only S16_LE, S16_BE, S24_LE, S24_3LE, "
+		       "S32_LE or S32_BE");
 		return -EINVAL;
 	}
 	svol->sformat = slave->format;
@@ -863,6 +869,7 @@ int snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
 	    sformat != SND_PCM_FORMAT_S16_LE &&
 	    sformat != SND_PCM_FORMAT_S16_BE &&
 	    sformat != SND_PCM_FORMAT_S24_3LE && 
+	    sformat != SND_PCM_FORMAT_S24_LE &&
 	    sformat != SND_PCM_FORMAT_S32_LE &&
 	    sformat != SND_PCM_FORMAT_S32_BE)
 		return -EINVAL;
@@ -1082,9 +1089,10 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
 		    sformat != SND_PCM_FORMAT_S16_LE &&
 		    sformat != SND_PCM_FORMAT_S16_BE &&
 		    sformat != SND_PCM_FORMAT_S24_3LE && 
+		    sformat != SND_PCM_FORMAT_S24_LE &&
 		    sformat != SND_PCM_FORMAT_S32_LE &&
 		    sformat != SND_PCM_FORMAT_S32_BE) {
-			SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format is supported");
+			SNDERR("only S16_LE, S16_BE, S24_LE, S24_3LE, S32_LE or S32_BE format is supported");
 			snd_config_delete(sconf);
 			return -EINVAL;
 		}
-- 
2.14.1

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-08 10:11 [PATCH] pcm: softvol: add support for S24_LE Jörg Krause
@ 2017-09-08 10:52 ` Clemens Ladisch
  2017-09-12  6:13   ` Jörg Krause
  0 siblings, 1 reply; 10+ messages in thread
From: Clemens Ladisch @ 2017-09-08 10:52 UTC (permalink / raw)
  To: Jörg Krause, alsa-devel

Jörg Krause wrote:
> Tested with a Wolfson WM8524 DAC on a i.MX6UL board running Linux version
> 4.13.0-next-20170907.

> +	case SND_PCM_FORMAT_S24_LE:
> +		/* 24bit samples, fallthrough */
>  	case SND_PCM_FORMAT_S32_LE:

S24_LE cannot be handled with the same algorithm as S32_LE.

I suspect that the hardware does not actually use S24_LE, and
that the driver uses the wrong label for this format.
Please describe exactly how the 24-bit sample is aligned into
the 32-bit memory cell.


Regards,
Clemens
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-08 10:52 ` Clemens Ladisch
@ 2017-09-12  6:13   ` Jörg Krause
  2017-09-12  6:19     ` Clemens Ladisch
  0 siblings, 1 reply; 10+ messages in thread
From: Jörg Krause @ 2017-09-12  6:13 UTC (permalink / raw)
  To: Clemens Ladisch, alsa-devel

On Fri, 2017-09-08 at 12:52 +0200, Clemens Ladisch wrote:
> Jörg Krause wrote:
> > Tested with a Wolfson WM8524 DAC on a i.MX6UL board running Linux version
> > 4.13.0-next-20170907.
> > +	case SND_PCM_FORMAT_S24_LE:
> > +		/* 24bit samples, fallthrough */
> >  	case SND_PCM_FORMAT_S32_LE:
> 
> S24_LE cannot be handled with the same algorithm as S32_LE.

That would have been too easy.

> I suspect that the hardware does not actually use S24_LE, and
> that the driver uses the wrong label for this format.

Maybe you are right about that. I will have a look.

> Please describe exactly how the 24-bit sample is aligned into
> the 32-bit memory cell.

According to this old post [1] it is aligned as followed:

00ffff3f 00ffff3f 00ebd96e 00ebd96e 00ffff7f 00ffff7f
Meaning the left-most byte is zeroed, right?

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2008-July/0090
99.html

Best regards,
Jörg Krause
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12  6:13   ` Jörg Krause
@ 2017-09-12  6:19     ` Clemens Ladisch
  2017-09-12  6:49       ` Jörg Krause
  0 siblings, 1 reply; 10+ messages in thread
From: Clemens Ladisch @ 2017-09-12  6:19 UTC (permalink / raw)
  To: Jörg Krause, alsa-devel

Jörg Krause wrote:
> On Fri, 2017-09-08 at 12:52 +0200, Clemens Ladisch wrote:
>> Please describe exactly how the 24-bit sample is aligned into
>> the 32-bit memory cell.
>
> According to this old post [1] it is aligned as followed:

That post talks about S24_LE.  I was asking about the actual hardware.

> Meaning the left-most byte is zeroed, right?

What does "left" mean when talking about memory?


Regards,
Clemens
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12  6:19     ` Clemens Ladisch
@ 2017-09-12  6:49       ` Jörg Krause
  2017-09-12  7:02         ` Clemens Ladisch
  0 siblings, 1 reply; 10+ messages in thread
From: Jörg Krause @ 2017-09-12  6:49 UTC (permalink / raw)
  To: Clemens Ladisch, alsa-devel

On Tue, 2017-09-12 at 08:19 +0200, Clemens Ladisch wrote:
> Jörg Krause wrote:
> > On Fri, 2017-09-08 at 12:52 +0200, Clemens Ladisch wrote:
> > > Please describe exactly how the 24-bit sample is aligned into
> > > the 32-bit memory cell.
> > 
> > According to this old post [1] it is aligned as followed:
> 
> That post talks about S24_LE.  I was asking about the actual hardware.

The i.MX6UL has a Synchronous Audio Interface (SAI), where the data in
the FIFO can be aligned anywhere within the 32-bit wide register
through the use of the First Bit Shifted configuration field. In the
corresponding Linux SAI driver the FBS field is set the way that data
alignment for 24-bit data is:

31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0
## ## ## ##   ## ## ## ## [           DATA[23:0]       ]


> > Meaning the left-most byte is zeroed, right?
> 
> What does "left" mean when talking about memory?

I should have said MSB first.
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12  6:49       ` Jörg Krause
@ 2017-09-12  7:02         ` Clemens Ladisch
  2017-09-12  7:12           ` Takashi Iwai
  0 siblings, 1 reply; 10+ messages in thread
From: Clemens Ladisch @ 2017-09-12  7:02 UTC (permalink / raw)
  To: Jörg Krause, alsa-devel

Jörg Krause wrote:
> The i.MX6UL has a Synchronous Audio Interface (SAI), where the data in
> the FIFO can be aligned anywhere within the 32-bit wide register
> through the use of the First Bit Shifted configuration field. In the
> corresponding Linux SAI driver the FBS field is set the way that data
> alignment for 24-bit data is:
>
> 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0
> ## ## ## ##   ## ## ## ## [           DATA[23:0]       ]

This indeed is S24_LE.

Which is an extremely uncommon format.  If possible, the driver should
be changed to align to the sample's MSB to the memory word's MSB, and
then label it as S32_LE.

>> S24_LE cannot be handled with the same algorithm as S32_LE.

To be precise: the sign in bit 23 must be preserved.


Regards,
Clemens
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12  7:02         ` Clemens Ladisch
@ 2017-09-12  7:12           ` Takashi Iwai
  2017-09-12 14:15             ` Jörg Krause
  0 siblings, 1 reply; 10+ messages in thread
From: Takashi Iwai @ 2017-09-12  7:12 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel, J6rg Krause

On Tue, 12 Sep 2017 09:02:47 +0200,
Clemens Ladisch wrote:
> 
> Jörg Krause wrote:
> > The i.MX6UL has a Synchronous Audio Interface (SAI), where the data in
> > the FIFO can be aligned anywhere within the 32-bit wide register
> > through the use of the First Bit Shifted configuration field. In the
> > corresponding Linux SAI driver the FBS field is set the way that data
> > alignment for 24-bit data is:
> >
> > 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0
> > ## ## ## ##   ## ## ## ## [           DATA[23:0]       ]
> 
> This indeed is S24_LE.
> 
> Which is an extremely uncommon format.  If possible, the driver should
> be changed to align to the sample's MSB to the memory word's MSB, and
> then label it as S32_LE.
> 
> >> S24_LE cannot be handled with the same algorithm as S32_LE.
> 
> To be precise: the sign in bit 23 must be preserved.

I guess the simple calculation with S24_LE using the current code
would work as long as the upper 8 bits are ignored by hardware.
The upper 8 bits would hold bogus bits, and clearing this would be an
extra action we'd need in addition.


thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12  7:12           ` Takashi Iwai
@ 2017-09-12 14:15             ` Jörg Krause
  2017-09-12 14:32               ` Takashi Iwai
  0 siblings, 1 reply; 10+ messages in thread
From: Jörg Krause @ 2017-09-12 14:15 UTC (permalink / raw)
  To: Takashi Iwai, Clemens Ladisch; +Cc: alsa-devel

On Tue, 2017-09-12 at 09:12 +0200, Takashi Iwai wrote:
> On Tue, 12 Sep 2017 09:02:47 +0200,
> Clemens Ladisch wrote:
> > 
> > Jörg Krause wrote:
> > > The i.MX6UL has a Synchronous Audio Interface (SAI), where the data in
> > > the FIFO can be aligned anywhere within the 32-bit wide register
> > > through the use of the First Bit Shifted configuration field. In the
> > > corresponding Linux SAI driver the FBS field is set the way that data
> > > alignment for 24-bit data is:
> > > 
> > > 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0
> > > ## ## ## ##   ## ## ## ## [           DATA[23:0]       ]
> > 
> > This indeed is S24_LE.
> > 
> > Which is an extremely uncommon format.  If possible, the driver should
> > be changed to align to the sample's MSB to the memory word's MSB, and
> > then label it as S32_LE.
> > 
> > > > S24_LE cannot be handled with the same algorithm as S32_LE.
> > 
> > To be precise: the sign in bit 23 must be preserved.
> 
> I guess the simple calculation with S24_LE using the current code
> would work as long as the upper 8 bits are ignored by hardware.
> The upper 8 bits would hold bogus bits, and clearing this would be an
> extra action we'd need in addition.

Thanks! I've copied the area convertion macro for S24_3LE and
explicitly set the upper 8 bits to 0:

"""
#define CONVERT_AREA_S24_LE() do {					\
	unsigned int ch, fr;						\
	unsigned char *src, *dst;					\
	int tmp;							\
	for (ch = 0; ch < channels; ch++) {				\
		src_area = &src_areas[ch];				\
		dst_area = &dst_areas[ch];				\
		src = snd_pcm_channel_area_addr(src_area, src_offset);	\
		dst = snd_pcm_channel_area_addr(dst_area, dst_offset);	\
		src_step = snd_pcm_channel_area_step(src_area);		\
		dst_step = snd_pcm_channel_area_step(dst_area);		\
		GET_VOL_SCALE;						\
		fr = frames;						\
		if (! vol_scale) {					\
			while (fr--) {					\
				dst[0] = dst[1] = dst[2] = dst[3] = 0;	\
				dst += dst_step;			\
			}						\
		} else if (vol_scale == 0xffff) {			\
			while (fr--) {					\
				dst[0] = src[0];			\
				dst[1] = src[1];			\
				dst[2] = src[2];			\
				dst[3] = 0;				\
				src += dst_step;			\
				dst += src_step;			\
			}						\
		} else {						\
			while (fr--) {					\
				tmp = src[0] |				\
				      (src[1] << 8) |			\
				      (((signed char *) src)[2] << 16);	\
				tmp = MULTI_DIV_24(tmp, vol_scale);	\
				dst[0] = tmp;				\
				dst[1] = tmp >> 8;			\
				dst[2] = tmp >> 16;			\
				dst[3] = 0;				\
				src += dst_step;			\
				dst += src_step;			\
			}						\
		}							\
	}								\
} while (0)
"""

Is that okay?

Jörg Krause
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12 14:15             ` Jörg Krause
@ 2017-09-12 14:32               ` Takashi Iwai
  2017-09-12 14:53                 ` Takashi Sakamoto
  0 siblings, 1 reply; 10+ messages in thread
From: Takashi Iwai @ 2017-09-12 14:32 UTC (permalink / raw)
  To: Jörg Krause; +Cc: alsa-devel, Clemens Ladisch

On Tue, 12 Sep 2017 16:15:58 +0200,
Jörg Krause wrote:
> 
> On Tue, 2017-09-12 at 09:12 +0200, Takashi Iwai wrote:
> > On Tue, 12 Sep 2017 09:02:47 +0200,
> > Clemens Ladisch wrote:
> > > 
> > > Jörg Krause wrote:
> > > > The i.MX6UL has a Synchronous Audio Interface (SAI), where the data in
> > > > the FIFO can be aligned anywhere within the 32-bit wide register
> > > > through the use of the First Bit Shifted configuration field. In the
> > > > corresponding Linux SAI driver the FBS field is set the way that data
> > > > alignment for 24-bit data is:
> > > > 
> > > > 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0
> > > > ## ## ## ##   ## ## ## ## [           DATA[23:0]       ]
> > > 
> > > This indeed is S24_LE.
> > > 
> > > Which is an extremely uncommon format.  If possible, the driver should
> > > be changed to align to the sample's MSB to the memory word's MSB, and
> > > then label it as S32_LE.
> > > 
> > > > > S24_LE cannot be handled with the same algorithm as S32_LE.
> > > 
> > > To be precise: the sign in bit 23 must be preserved.
> > 
> > I guess the simple calculation with S24_LE using the current code
> > would work as long as the upper 8 bits are ignored by hardware.
> > The upper 8 bits would hold bogus bits, and clearing this would be an
> > extra action we'd need in addition.
> 
> Thanks! I've copied the area convertion macro for S24_3LE and
> explicitly set the upper 8 bits to 0:
> 
> """
> #define CONVERT_AREA_S24_LE() do {					\
> 	unsigned int ch, fr;						\
> 	unsigned char *src, *dst;					\
> 	int tmp;							\
> 	for (ch = 0; ch < channels; ch++) {				\
> 		src_area = &src_areas[ch];				\
> 		dst_area = &dst_areas[ch];				\
> 		src = snd_pcm_channel_area_addr(src_area, src_offset);	\
> 		dst = snd_pcm_channel_area_addr(dst_area, dst_offset);	\
> 		src_step = snd_pcm_channel_area_step(src_area);		\
> 		dst_step = snd_pcm_channel_area_step(dst_area);		\
> 		GET_VOL_SCALE;						\
> 		fr = frames;						\
> 		if (! vol_scale) {					\
> 			while (fr--) {					\
> 				dst[0] = dst[1] = dst[2] = dst[3] = 0;	\
> 				dst += dst_step;			\
> 			}						\
> 		} else if (vol_scale == 0xffff) {			\
> 			while (fr--) {					\
> 				dst[0] = src[0];			\
> 				dst[1] = src[1];			\
> 				dst[2] = src[2];			\
> 				dst[3] = 0;				\
> 				src += dst_step;			\
> 				dst += src_step;			\
> 			}						\
> 		} else {						\
> 			while (fr--) {					\
> 				tmp = src[0] |				\
> 				      (src[1] << 8) |			\
> 				      (((signed char *) src)[2] << 16);	\
> 				tmp = MULTI_DIV_24(tmp, vol_scale);	\
> 				dst[0] = tmp;				\
> 				dst[1] = tmp >> 8;			\
> 				dst[2] = tmp >> 16;			\
> 				dst[3] = 0;				\
> 				src += dst_step;			\
> 				dst += src_step;			\
> 			}						\
> 		}							\
> 	}								\
> } while (0)
> """
> 
> Is that okay?

You can simply mask 0xffffff (or 0xffffff00, depending on CPU-native
or not) to the int value instead of assigning / calculating each byte.
And it's needed only when vol_scale !=0 && vol_scale != 0xffff.


thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] pcm: softvol: add support for S24_LE
  2017-09-12 14:32               ` Takashi Iwai
@ 2017-09-12 14:53                 ` Takashi Sakamoto
  0 siblings, 0 replies; 10+ messages in thread
From: Takashi Sakamoto @ 2017-09-12 14:53 UTC (permalink / raw)
  To: Takashi Iwai, Jörg Krause; +Cc: alsa-devel, Clemens Ladisch

Hi,

On 2017年09月12日 23:32, Takashi Iwai wrote:
> You can simply mask 0xffffff (or 0xffffff00, depending on CPU-native
> or not) to the int value instead of assigning / calculating each byte.
> And it's needed only when vol_scale !=0 && vol_scale != 0xffff.

Vumeter implementation of aplay in alsa-utils.git generates mask from 
return value of 'snd_pcm_format_silence[|_16|_32|_64]()'. I suppose this 
is also useful in your case.


Regards

Takashi Sakamoto
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-09-12 14:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-08 10:11 [PATCH] pcm: softvol: add support for S24_LE Jörg Krause
2017-09-08 10:52 ` Clemens Ladisch
2017-09-12  6:13   ` Jörg Krause
2017-09-12  6:19     ` Clemens Ladisch
2017-09-12  6:49       ` Jörg Krause
2017-09-12  7:02         ` Clemens Ladisch
2017-09-12  7:12           ` Takashi Iwai
2017-09-12 14:15             ` Jörg Krause
2017-09-12 14:32               ` Takashi Iwai
2017-09-12 14:53                 ` Takashi Sakamoto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.