Page MenuHomeFreeBSD

D47638.id147533.diff
No OneTemporary

D47638.id147533.diff

diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -966,9 +966,13 @@
#if BYTE_ORDER == LITTLE_ENDIAN
{ "s32le", "s32", "32", AFMT_S32_LE },
{ "s32be", NULL, NULL, AFMT_S32_BE },
+ { "f32le", "f32", NULL, AFMT_F32_LE },
+ { "f32be", NULL, NULL, AFMT_F32_BE },
#else
{ "s32le", NULL, NULL, AFMT_S32_LE },
{ "s32be", "s32", "32", AFMT_S32_BE },
+ { "f32le", NULL, NULL, AFMT_F32_LE },
+ { "f32be", "f32", NULL, AFMT_F32_BE },
#endif
{ "u32le", NULL, NULL, AFMT_U32_LE },
{ "u32be", NULL, NULL, AFMT_U32_BE },
diff --git a/sys/dev/sound/pcm/feeder_format.c b/sys/dev/sound/pcm/feeder_format.c
--- a/sys/dev/sound/pcm/feeder_format.c
+++ b/sys/dev/sound/pcm/feeder_format.c
@@ -64,8 +64,12 @@
__always_inline intpcm_t
pcm_sample_read(uint8_t *src, int fmt)
{
+ float fv;
intpcm_t v;
+ if (fmt == AFMT_F32_LE || fmt == AFMT_F32_BE)
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+
switch (fmt) {
#if BYTE_ORDER == LITTLE_ENDIAN
case AFMT_S16_LE:
@@ -94,6 +98,19 @@
v = INTPCM_T(src[3] | src[2] << 8 | src[1] << 16 |
((int8_t)src[0] ^ 0x80) << 24);
break;
+ case AFMT_F32_LE:
+ v = INTPCM_T(*(float *)src * (float)PCM_S32_MAX);
+ break;
+ case AFMT_F32_BE:
+ fv = *(float *)src;
+ memcpy(&v, &fv, sizeof(v));
+ v = ((uint32_t)v & 0x000000ff) << 24 |
+ (v & 0x0000ff00) << 8 |
+ (v & 0x00ff0000) << 16 |
+ (v & 0xff000000) << 24;
+ memcpy(&fv, &v, sizeof(fv));
+ v = INTPCM_T(fv * (float)PCM_S32_MAX);
+ break;
#else /* BYTE_ORDER != LITTLE_ENDIAN */
case AFMT_S16_LE:
v = INTPCM_T(src[0] | (int8_t)src[1] << 8);
@@ -121,6 +138,19 @@
case AFMT_U32_BE:
v = INTPCM_T((int32_t)(*(uint32_t *)src) ^ 0x80000000);
break;
+ case AFMT_F32_LE:
+ fv = *(float *)src;
+ memcpy(&v, &fv, sizeof(v));
+ v = ((uint32_t)v & 0x000000ff) << 24 |
+ (v & 0x0000ff00) << 8 |
+ (v & 0x00ff0000) << 16 |
+ (v & 0xff000000) << 24;
+ memcpy(&fv, &v, sizeof(fv));
+ v = INTPCM_T(fv * (float)PCM_S32_MAX);
+ break;
+ case AFMT_F32_BE:
+ v = INTPCM_T(*(float *)src * (float)PCM_S32_MAX);
+ break;
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
case AFMT_S8:
v = INTPCM_T(*(int8_t *)src);
@@ -156,6 +186,9 @@
return (0);
}
+ if (fmt == AFMT_F32_LE || fmt == AFMT_F32_BE)
+ fpu_kern_leave(curthread, NULL);
+
#ifndef SND_PCM_64
v >>= PCM_FXSHIFT;
#endif
@@ -166,10 +199,16 @@
__always_inline void
pcm_sample_write(uint8_t *dst, intpcm_t v, int fmt)
{
+ uint8_t *tmp;
+ float fv;
+
#ifndef SND_PCM_64
v <<= PCM_FXSHIFT;
#endif
+ if (fmt == AFMT_F32_LE || fmt == AFMT_F32_BE)
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+
switch (fmt) {
#if BYTE_ORDER == LITTLE_ENDIAN
case AFMT_S16_LE:
@@ -204,6 +243,17 @@
dst[1] = v >> 16;
dst[0] = (v >> 24) ^ 0x80;
break;
+ case AFMT_F32_LE:
+ *(float *)dst = (float)v / (float)PCM_S32_MAX;
+ break;
+ case AFMT_F32_BE:
+ fv = (float)v / (float)PCM_S32_MAX;
+ tmp = (uint8_t *)&fv;
+ dst[0] = tmp[3];
+ dst[1] = tmp[2];
+ dst[2] = tmp[1];
+ dst[3] = tmp[0];
+ break;
#else /* BYTE_ORDER != LITTLE_ENDIAN */
case AFMT_S16_LE:
dst[1] = v;
@@ -237,6 +287,17 @@
case AFMT_U32_BE:
*(uint32_t *)dst = v ^ 0x80000000;
break;
+ case AFMT_F32_LE:
+ fv = (float)v / (float)PCM_S32_MAX;
+ tmp = (uint8_t *)&fv;
+ dst[0] = tmp[3];
+ dst[1] = tmp[2];
+ dst[2] = tmp[1];
+ dst[3] = tmp[0];
+ break;
+ case AFMT_F32_BE:
+ *(float *)dst = (float)v / (float)PCM_S32_MAX;
+ break;
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
case AFMT_S8:
*(int8_t *)dst = v;
@@ -277,6 +338,9 @@
printf("%s(): unknown format: %08x\n", __func__, fmt);
break;
}
+
+ if (fmt == AFMT_F32_LE || fmt == AFMT_F32_BE)
+ fpu_kern_leave(curthread, NULL);
}
static const struct {
@@ -300,6 +364,8 @@
{ AFMT_MU_LAW, 24 },
{ AFMT_A_LAW, 24 },
{ AFMT_AC3, 16 },
+ { AFMT_F32_LE, 0 },
+ { AFMT_F32_BE, 0 },
};
static int
diff --git a/sys/dev/sound/pcm/feeder_mixer.c b/sys/dev/sound/pcm/feeder_mixer.c
--- a/sys/dev/sound/pcm/feeder_mixer.c
+++ b/sys/dev/sound/pcm/feeder_mixer.c
@@ -64,10 +64,12 @@
#if BYTE_ORDER == LITTLE_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
FEEDMIXER_DECLARE(S, 16, LE)
FEEDMIXER_DECLARE(S, 32, LE)
+FEEDMIXER_DECLARE(F, 32, LE)
#endif
#if BYTE_ORDER == BIG_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
FEEDMIXER_DECLARE(S, 16, BE)
FEEDMIXER_DECLARE(S, 32, BE)
+FEEDMIXER_DECLARE(F, 32, BE)
#endif
#ifdef SND_FEEDER_MULTIFORMAT
FEEDMIXER_DECLARE(S, 8, NE)
@@ -99,10 +101,12 @@
#if BYTE_ORDER == LITTLE_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
FEEDMIXER_ENTRY(S, 16, LE),
FEEDMIXER_ENTRY(S, 32, LE),
+ FEEDMIXER_ENTRY(F, 32, LE),
#endif
#if BYTE_ORDER == BIG_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
FEEDMIXER_ENTRY(S, 16, BE),
FEEDMIXER_ENTRY(S, 32, BE),
+ FEEDMIXER_ENTRY(F, 32, BE),
#endif
#ifdef SND_FEEDER_MULTIFORMAT
FEEDMIXER_ENTRY(S, 24, LE),
diff --git a/sys/dev/sound/pcm/pcm.h b/sys/dev/sound/pcm/pcm.h
--- a/sys/dev/sound/pcm/pcm.h
+++ b/sys/dev/sound/pcm/pcm.h
@@ -120,6 +120,7 @@
#define PCM_CLAMP_U16(val) PCM_CLAMP_S16(val)
#define PCM_CLAMP_U24(val) PCM_CLAMP_S24(val)
#define PCM_CLAMP_U32(val) PCM_CLAMP_S32(val)
+#define PCM_CLAMP_F32(val) PCM_CLAMP_S32(val)
extern __always_inline intpcm_t pcm_sample_read(uint8_t *, int);
extern __always_inline void pcm_sample_write(uint8_t *, intpcm_t, int);
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -161,13 +161,15 @@
(((var)<(low))? (low) : ((var)>(high))? (high) : (var))
/* make figuring out what a format is easier. got AFMT_STEREO already */
-#define AFMT_32BIT (AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE)
+#define AFMT_32BIT (AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE | \
+ AFMT_F32_LE | AFMT_F32_BE)
#define AFMT_24BIT (AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE)
#define AFMT_16BIT (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)
#define AFMT_G711 (AFMT_MU_LAW | AFMT_A_LAW)
#define AFMT_8BIT (AFMT_G711 | AFMT_U8 | AFMT_S8)
#define AFMT_SIGNED (AFMT_S32_LE | AFMT_S32_BE | AFMT_S24_LE | AFMT_S24_BE | \
- AFMT_S16_LE | AFMT_S16_BE | AFMT_S8)
+ AFMT_S16_LE | AFMT_S16_BE | AFMT_S8 | AFMT_F32_LE | \
+ AFMT_F32_BE)
#define AFMT_BIGENDIAN (AFMT_S32_BE | AFMT_U32_BE | AFMT_S24_BE | AFMT_U24_BE | \
AFMT_S16_BE | AFMT_U16_BE)
diff --git a/sys/sys/soundcard.h b/sys/sys/soundcard.h
--- a/sys/sys/soundcard.h
+++ b/sys/sys/soundcard.h
@@ -184,6 +184,8 @@
#define AFMT_S24_BE 0x00020000 /* Big endian signed 24-bit */
#define AFMT_U24_LE 0x00040000 /* Little endian unsigned 24-bit */
#define AFMT_U24_BE 0x00080000 /* Big endian unsigned 24-bit */
+#define AFMT_F32_LE 0x10000000 /* Little endian 32-bit floating point */
+#define AFMT_F32_BE 0x20000000 /* Big endian 32-bit floating point */
/* Machine dependent AFMT_* definitions. */
#if BYTE_ORDER == LITTLE_ENDIAN
@@ -199,6 +201,7 @@
#define AFMT_U16_OE AFMT_U16_BE
#define AFMT_U24_OE AFMT_U24_BE
#define AFMT_U32_OE AFMT_U32_BE
+#define AFMT_F32_NE AFMT_F32_LE
#else
#define AFMT_S16_OE AFMT_S16_LE
#define AFMT_S24_OE AFMT_S24_LE
@@ -212,8 +215,11 @@
#define AFMT_U16_NE AFMT_U16_BE
#define AFMT_U24_NE AFMT_U24_BE
#define AFMT_U32_NE AFMT_U32_BE
+#define AFMT_F32_NE AFMT_F32_BE
#endif
+#define AFMT_FLOAT AFMT_F32_NE /* compatibility alias */
+
#define AFMT_STEREO 0x10000000 /* can do/want stereo */
/*

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 13, 12:37 AM (19 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16619632
Default Alt Text
D47638.id147533.diff (7 KB)

Event Timeline