Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Juergen Kreileder <jk@blackdown.de>
To: Takashi Iwai <tiwai@suse.de>
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: Any missing patches?
Date: Mon, 20 Mar 2006 21:26:47 +0100	[thread overview]
Message-ID: <871wwwq2uw.fsf@blackdown.de> (raw)
In-Reply-To: <s5hmzfl9cql.wl%tiwai@suse.de> (Takashi Iwai's message of "Mon, 20 Mar 2006 19:45:22 +0100")

Takashi Iwai <tiwai@suse.de> writes:

> if someone has patches intended for merging to ALSA tree, please
> submit them ASAP.
>
> I think the current ALSA CVS tree is forming to a relatively good
> shape now, and it's good time to push Linux kernel tree, too.
> Let's be not too late to ride a bus.

Here's a patch which adds support for S24_3LE and byte-swapped S16 and
S32 to softvol.  I've tested S24_3LE and byte-swapped S16 on powerpc
with snd-usb-audio.  All other cases are untested so far.
(Config at http://blog.blackdown.de/static/alsa/USB-Audio.conf)


        Juergen

Signed-off-by: Juergen Kreileder <jk@blackdown.de>

--- o/alsa-lib-1.0.11rc3/src/pcm/pcm_softvol.c	2005-09-02 18:36:40.000000000 +0200
+++ alsa-lib-1.0.11rc3/src/pcm/pcm_softvol.c	2006-03-10 02:46:39.000000000 +0100
@@ -96,10 +96,10 @@ typedef union {
 	int i;
 	short s[2];
 } val_t;
-static inline int MULTI_DIV_int(int a, unsigned short b)
+static inline int MULTI_DIV_int(int a, unsigned short b, int swap)
 {
 	val_t v, x, y;
-	v.i = a;
+	v.i = swap ? bswap_32(a) : a;
 	y.i = 0;
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 	x.i = (unsigned int)v.s[0] * b;
@@ -110,11 +110,14 @@ static inline int MULTI_DIV_int(int a, u
 	y.s[1] = x.s[0];
 	y.i += (int)v.s[0] * b;
 #endif
-	return y.i;
+	return swap ? bswap_32(y.i) : y.i;
 }
 
 /* (16bit x 16bit) >> 16 */
-#define MULTI_DIV_short(src,scale) (((int)(src) * (scale)) >> VOL_SCALE_SHIFT)
+#define MULTI_DIV_short(src, scale, swap)				  \
+(swap									  \
+ ? bswap_16(((short) bswap_16(src) * (scale)) >> VOL_SCALE_SHIFT)   \
+ : (((int) (src) * (scale)) >> VOL_SCALE_SHIFT))
 
 #endif /* DOC_HIDDEN */
 
@@ -125,7 +128,7 @@ static inline int MULTI_DIV_int(int a, u
  */
 
 #ifndef DOC_HIDDEN
-#define CONVERT_AREA(TYPE) do {	\
+#define CONVERT_AREA(TYPE, swap) do {	\
 	unsigned int ch, fr; \
 	TYPE *src, *dst; \
 	for (ch = 0; ch < channels; ch++) { \
@@ -150,15 +153,55 @@ static inline int MULTI_DIV_int(int a, u
 			} \
 		} else { \
 			while (fr--) { \
-				*dst = MULTI_DIV_##TYPE(*src, vol_scale);\
+				*dst = (TYPE) MULTI_DIV_##TYPE(*src, vol_scale, swap); \
 				src += src_step; \
 				dst += dst_step; \
 			} \
 		} \
 	} \
 } while (0)
-	
 
+#define CONVERT_AREA_S24_3LE() 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] = 0;		\
+				dst += dst_step;			\
+			}						\
+		} else if (vol_scale == 0xffff) {			\
+			while (fr--) {					\
+				dst[0] = src[0];			\
+				dst[1] = src[1];			\
+				dst[2] = src[2];			\
+				src += dst_step;			\
+				dst += src_step;			\
+			}						\
+		} else {						\
+			while (fr--) {					\
+				tmp = src[0] |				\
+				      (src[1] << 8) |			\
+				      (((signed char *) src)[2] << 16);	\
+				tmp = MULTI_DIV_int(tmp, vol_scale, 0);	\
+				dst[0] = tmp;				\
+				dst[1] = tmp >> 8;			\
+				dst[2] = tmp >> 16;			\
+				src += dst_step;			\
+				dst += src_step;			\
+			}						\
+		}							\
+	}								\
+} while (0)
 		
 #define GET_VOL_SCALE \
 	switch (ch) { \
@@ -204,12 +247,24 @@ static void softvol_convert_stereo_vol(s
 	vol[0] = svol->dB_value[svol->cur_vol[0]];
 	vol[1] = svol->dB_value[svol->cur_vol[1]];
 	vol_c = svol->dB_value[(svol->cur_vol[0] + svol->cur_vol[1]) / 2];
-	if (svol->sformat == SND_PCM_FORMAT_S16) {
+	switch (svol->sformat) {
+	case SND_PCM_FORMAT_S16_LE:
+	case SND_PCM_FORMAT_S16_BE:
 		/* 16bit samples */
-		CONVERT_AREA(short);
-	} else {
+		CONVERT_AREA(short, 
+			     !snd_pcm_format_cpu_endian(svol->sformat));
+		break;
+	case SND_PCM_FORMAT_S32_LE:
+	case SND_PCM_FORMAT_S32_BE:
 		/* 32bit samples */
-		CONVERT_AREA(int);
+		CONVERT_AREA(int,
+			     !snd_pcm_format_cpu_endian(svol->sformat));
+		break;
+	case SND_PCM_FORMAT_S24_3LE:
+		CONVERT_AREA_S24_3LE();
+		break;
+	default:
+		break;
 	}
 }
 
@@ -240,12 +295,24 @@ static void softvol_convert_mono_vol(snd
 	}
 
 	vol_scale = svol->dB_value[svol->cur_vol[0]];
-	if (svol->sformat == SND_PCM_FORMAT_S16) {
+	switch (svol->sformat) {
+	case SND_PCM_FORMAT_S16_LE:
+	case SND_PCM_FORMAT_S16_BE:
 		/* 16bit samples */
-		CONVERT_AREA(short);
-	} else {
+		CONVERT_AREA(short, 
+			     !snd_pcm_format_cpu_endian(svol->sformat));
+		break;
+	case SND_PCM_FORMAT_S32_LE:
+	case SND_PCM_FORMAT_S32_BE:
 		/* 32bit samples */
-		CONVERT_AREA(int);
+		CONVERT_AREA(int,
+			     !snd_pcm_format_cpu_endian(svol->sformat));
+		break;
+	case SND_PCM_FORMAT_S24_3LE:
+		CONVERT_AREA_S24_3LE();
+		break;
+	default:
+		break;
 	}
 }
 
@@ -287,14 +354,25 @@ static int snd_pcm_softvol_close(snd_pcm
 	return 0;
 }
 
-static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
+static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm,
 					      snd_pcm_hw_params_t *params)
 {
 	int err;
+	snd_pcm_softvol_t *svol = pcm->private_data;
 	snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_SHM };
 	snd_pcm_format_mask_t format_mask = {
-		{ (1U << SND_PCM_FORMAT_S16) | (1U << SND_PCM_FORMAT_S32) }
+		{
+			(1ULL << SND_PCM_FORMAT_S16_LE) |
+			(1ULL << SND_PCM_FORMAT_S16_BE) |
+			(1ULL << SND_PCM_FORMAT_S32_LE) |
+ 			(1ULL << SND_PCM_FORMAT_S32_BE),
+			(1ULL << (SND_PCM_FORMAT_S24_3LE - 32))
+		}
 	};
+	if (svol->sformat != SND_PCM_FORMAT_UNKNOWN) {
+		snd_pcm_format_mask_none(&format_mask);
+		snd_pcm_format_mask_set(&format_mask, svol->sformat);
+	}
 	err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_ACCESS,
 					 &access_mask);
 	if (err < 0)
@@ -396,9 +474,13 @@ static int snd_pcm_softvol_hw_params(snd
 					  snd_pcm_generic_hw_params);
 	if (err < 0)
 		return err;
-	if (slave->format != SND_PCM_FORMAT_S16 &&
-	    slave->format != SND_PCM_FORMAT_S32) {
-		SNDERR("softvol supports only S16 or S32");
+	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_S32_LE &&
+	    slave->format != SND_PCM_FORMAT_S32_BE) {
+		SNDERR("softvol supports only S16_LE, S16_BE, S24_3LE, S32_LE "
+		       " or S32_BE");
 		return -EINVAL;
 	}
 	svol->sformat = slave->format;
@@ -619,8 +701,11 @@ int snd_pcm_softvol_open(snd_pcm_t **pcm
 	int err;
 	assert(pcmp && slave);
 	if (sformat != SND_PCM_FORMAT_UNKNOWN &&
-	    sformat != SND_PCM_FORMAT_S16 &&
-	    sformat != SND_PCM_FORMAT_S32)
+	    sformat != SND_PCM_FORMAT_S16_LE &&
+	    sformat != SND_PCM_FORMAT_S16_BE &&
+	    sformat != SND_PCM_FORMAT_S24_3LE && 
+	    sformat != SND_PCM_FORMAT_S32_LE &&
+	    sformat != SND_PCM_FORMAT_S32_BE)
 		return -EINVAL;
 	svol = calloc(1, sizeof(*svol));
 	if (! svol)
@@ -808,9 +893,13 @@ int _snd_pcm_softvol_open(snd_pcm_t **pc
 	if (err < 0)
 		return err;
 	if (sformat != SND_PCM_FORMAT_UNKNOWN &&
-	    sformat != SND_PCM_FORMAT_S16 &&
-	    sformat != SND_PCM_FORMAT_S32) {
-		SNDERR("only S16 or S32 format is supported");
+	    sformat != SND_PCM_FORMAT_S16_LE &&
+	    sformat != SND_PCM_FORMAT_S16_BE &&
+	    sformat != SND_PCM_FORMAT_S24_3LE && 
+	    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");
 		snd_config_delete(sconf);
 		return -EINVAL;
 	}
=

-- 
Juergen Kreileder, Blackdown Java-Linux Team
http://blog.blackdown.de/


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642

  parent reply	other threads:[~2006-03-20 20:26 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-20 18:45 Any missing patches? Takashi Iwai
2006-03-20 20:18 ` Juergen Kreileder
2006-03-20 20:27   ` Takashi Iwai
2006-03-20 21:15     ` Juergen Kreileder
2006-03-21 10:52       ` Takashi Iwai
2006-03-20 20:26 ` Juergen Kreileder [this message]
2006-03-20 20:35   ` Takashi Iwai
2006-03-21 11:07   ` Takashi Iwai
2006-03-21  9:15 ` RE : " Thibault LE MEUR
2006-03-21 11:06   ` Takashi Iwai
2006-03-21 10:18 ` Rimas Kudelis
2006-03-21 10:54   ` Takashi Iwai
2006-03-21 11:30     ` Rimas Kudelis
2006-03-21 11:39       ` Takashi Iwai
2006-03-21 21:02     ` Rimas Kudelis
2006-03-21 22:06       ` Lee Revell
2006-03-22 11:02         ` Takashi Iwai
2006-03-22  1:37 ` Lee Revell
2006-03-22  4:15   ` Lee Revell
2006-03-22 18:32 ` Lee Revell
2006-03-22 20:16   ` Takashi Iwai
2006-04-05  3:58 ` [PATCH] asihpi unbalanced spinlocks Eliot Blennerhassett
2006-04-06 19:31   ` Takashi Iwai
     [not found] <20060321223803.318AD16C42@sc8-sf-spam2.sourceforge.net>
2006-03-22  2:37 ` Any missing patches? Jonathan Woithe
2006-03-22 10:56   ` Takashi Iwai
2006-03-22 23:08     ` Jonathan Woithe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871wwwq2uw.fsf@blackdown.de \
    --to=jk@blackdown.de \
    --cc=alsa-devel@lists.sourceforge.net \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox