mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Enhanced bitmasks in PCM - added support for more formats by Takashi and me
This commit is contained in:
parent
84730c976f
commit
16b3bf447c
14 changed files with 893 additions and 162 deletions
|
|
@ -160,7 +160,31 @@ typedef enum _snd_pcm_format {
|
|||
SND_PCM_FORMAT_GSM,
|
||||
/** Special */
|
||||
SND_PCM_FORMAT_SPECIAL = 31,
|
||||
SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_SPECIAL,
|
||||
/** Signed 24bit Little Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_S24_3LE = 32,
|
||||
/** Signed 24bit Big Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_S24_3BE,
|
||||
/** Unsigned 24bit Little Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_U24_3LE,
|
||||
/** Unsigned 24bit Big Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_U24_3BE,
|
||||
/** Signed 20bit Little Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_S20_3LE,
|
||||
/** Signed 20bit Big Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_S20_3BE,
|
||||
/** Unsigned 20bit Little Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_U20_3LE,
|
||||
/** Unsigned 20bit Big Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_U20_3BE,
|
||||
/** Signed 18bit Little Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_S18_3LE,
|
||||
/** Signed 18bit Big Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_S18_3BE,
|
||||
/** Unsigned 18bit Little Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_U18_3LE,
|
||||
/** Unsigned 18bit Big Endian in 3bytes format */
|
||||
SND_PCM_FORMAT_U18_3BE,
|
||||
SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_U18_3BE,
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
/** Signed 16 bit CPU endian */
|
||||
|
|
@ -817,7 +841,7 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format);
|
|||
int snd_pcm_format_cpu_endian(snd_pcm_format_t format);
|
||||
int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */
|
||||
int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */
|
||||
snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian);
|
||||
snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian);
|
||||
ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
|
||||
u_int8_t snd_pcm_format_silence(snd_pcm_format_t format);
|
||||
u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
typedef struct _snd_mask snd_mask_t;
|
||||
|
||||
#define SND_MASK_MAX 31
|
||||
#define SND_MASK_MAX 64
|
||||
|
||||
#ifdef SND_MASK_INLINE
|
||||
#include "mask_inline.h"
|
||||
|
|
|
|||
|
|
@ -23,15 +23,11 @@
|
|||
|
||||
#define MASK_INLINE static inline
|
||||
|
||||
#ifndef MASK_MASK
|
||||
#define MASK_MAX 31
|
||||
#endif
|
||||
#define MASK_MAX SND_MASK_MAX
|
||||
#define MASK_SIZE (MASK_MAX / 32)
|
||||
|
||||
struct _snd_mask {
|
||||
unsigned int bits;
|
||||
};
|
||||
|
||||
#define snd_mask_bits(mask) ((mask)->bits)
|
||||
#define MASK_OFS(i) ((i) >> 5)
|
||||
#define MASK_BIT(i) (1U << ((i) & 31))
|
||||
|
||||
MASK_INLINE unsigned int ld2(u_int32_t v)
|
||||
{
|
||||
|
|
@ -74,106 +70,143 @@ MASK_INLINE size_t snd_mask_sizeof(void)
|
|||
|
||||
MASK_INLINE void snd_mask_none(snd_mask_t *mask)
|
||||
{
|
||||
snd_mask_bits(mask) = 0;
|
||||
memset(mask, 0, sizeof(*mask));
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_any(snd_mask_t *mask)
|
||||
{
|
||||
snd_mask_bits(mask) = ~0U;
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_load(snd_mask_t *mask, unsigned int msk)
|
||||
{
|
||||
snd_mask_bits(mask) = msk;
|
||||
memset(mask, 0xff, MASK_SIZE * 4);
|
||||
}
|
||||
|
||||
MASK_INLINE int snd_mask_empty(const snd_mask_t *mask)
|
||||
{
|
||||
return snd_mask_bits(mask) == 0;
|
||||
int i;
|
||||
for (i = 0; i < MASK_SIZE; i++)
|
||||
if (mask->bits[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
MASK_INLINE int snd_mask_full(const snd_mask_t *mask)
|
||||
{
|
||||
return snd_mask_bits(mask) == ~0U;
|
||||
int i;
|
||||
for (i = 0; i < MASK_SIZE; i++)
|
||||
if (mask->bits[i] != 0xffffffff)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
MASK_INLINE unsigned int snd_mask_count(const snd_mask_t *mask)
|
||||
{
|
||||
return hweight32(snd_mask_bits(mask));
|
||||
int i, w = 0;
|
||||
for (i = 0; i < MASK_SIZE; i++)
|
||||
w += hweight32(mask->bits[i]);
|
||||
return w;
|
||||
}
|
||||
|
||||
MASK_INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
|
||||
{
|
||||
int i;
|
||||
assert(!snd_mask_empty(mask));
|
||||
return ffs(snd_mask_bits(mask)) - 1;
|
||||
for (i = 0; i < MASK_SIZE; i++) {
|
||||
if (mask->bits[i])
|
||||
return ffs(mask->bits[i]) - 1 + (i << 5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MASK_INLINE unsigned int snd_mask_max(const snd_mask_t *mask)
|
||||
{
|
||||
int i;
|
||||
assert(!snd_mask_empty(mask));
|
||||
return ld2(snd_mask_bits(mask));
|
||||
for (i = MASK_SIZE - 1; i >= 0; i--) {
|
||||
if (mask->bits[i])
|
||||
return ld2(mask->bits[i]) + (i << 5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_set(snd_mask_t *mask, unsigned int val)
|
||||
{
|
||||
assert(val <= SND_MASK_MAX);
|
||||
snd_mask_bits(mask) |= (1U << val);
|
||||
mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_reset(snd_mask_t *mask, unsigned int val)
|
||||
{
|
||||
assert(val <= SND_MASK_MAX);
|
||||
snd_mask_bits(mask) &= ~(1U << val);
|
||||
mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
|
||||
{
|
||||
unsigned int i;
|
||||
assert(to <= SND_MASK_MAX && from <= to);
|
||||
snd_mask_bits(mask) |= ((1U << (from - to + 1)) - 1) << from;
|
||||
for (i = from; i <= to; i++)
|
||||
mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
|
||||
{
|
||||
unsigned int i;
|
||||
assert(to <= SND_MASK_MAX && from <= to);
|
||||
snd_mask_bits(mask) &= ~(((1U << (from - to + 1)) - 1) << from);
|
||||
for (i = from; i <= to; i++)
|
||||
mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_leave(snd_mask_t *mask, unsigned int val)
|
||||
{
|
||||
unsigned int v;
|
||||
assert(val <= SND_MASK_MAX);
|
||||
snd_mask_bits(mask) &= 1U << val;
|
||||
v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
|
||||
snd_mask_none(mask);
|
||||
mask->bits[MASK_OFS(val)] = v;
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v)
|
||||
{
|
||||
snd_mask_bits(mask) &= snd_mask_bits(v);
|
||||
int i;
|
||||
for (i = 0; i < MASK_SIZE; i++)
|
||||
mask->bits[i] &= v->bits[i];
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_union(snd_mask_t *mask, const snd_mask_t *v)
|
||||
{
|
||||
snd_mask_bits(mask) |= snd_mask_bits(v);
|
||||
int i;
|
||||
for (i = 0; i < MASK_SIZE; i++)
|
||||
mask->bits[i] |= v->bits[i];
|
||||
}
|
||||
|
||||
MASK_INLINE int snd_mask_eq(const snd_mask_t *mask, const snd_mask_t *v)
|
||||
{
|
||||
return snd_mask_bits(mask) == snd_mask_bits(v);
|
||||
return ! memcmp(mask, v, MASK_SIZE * 4);
|
||||
}
|
||||
|
||||
MASK_INLINE void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v)
|
||||
{
|
||||
snd_mask_bits(mask) = snd_mask_bits(v);
|
||||
*mask = *v;
|
||||
}
|
||||
|
||||
MASK_INLINE int snd_mask_test(const snd_mask_t *mask, unsigned int val)
|
||||
{
|
||||
assert(val <= SND_MASK_MAX);
|
||||
return snd_mask_bits(mask) & (1U << val);
|
||||
return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
|
||||
}
|
||||
|
||||
MASK_INLINE int snd_mask_single(const snd_mask_t *mask)
|
||||
{
|
||||
int i, c = 0;
|
||||
assert(!snd_mask_empty(mask));
|
||||
return !(snd_mask_bits(mask) & (snd_mask_bits(mask) - 1));
|
||||
for (i = 0; i < MASK_SIZE; i++) {
|
||||
if (! mask->bits[i])
|
||||
continue;
|
||||
if (mask->bits[i] & (mask->bits[i] - 1))
|
||||
return 0;
|
||||
if (c)
|
||||
return 0;
|
||||
c++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
MASK_INLINE int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v)
|
||||
|
|
@ -252,5 +285,9 @@ MASK_INLINE int snd_mask_always_eq(const snd_mask_t *m1, const snd_mask_t *m2)
|
|||
|
||||
MASK_INLINE int snd_mask_never_eq(const snd_mask_t *m1, const snd_mask_t *m2)
|
||||
{
|
||||
return (snd_mask_bits(m1) & snd_mask_bits(m2)) == 0;
|
||||
int i;
|
||||
for (i = 0; i < MASK_SIZE; i++)
|
||||
if (m1->bits[i] & m2->bits[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1200,6 +1200,18 @@ static const char *snd_pcm_format_names[] = {
|
|||
FORMAT(MPEG),
|
||||
FORMAT(GSM),
|
||||
FORMAT(SPECIAL),
|
||||
FORMAT(S24_3LE),
|
||||
FORMAT(S24_3BE),
|
||||
FORMAT(U24_3LE),
|
||||
FORMAT(U24_3BE),
|
||||
FORMAT(S20_3LE),
|
||||
FORMAT(S20_3BE),
|
||||
FORMAT(U20_3LE),
|
||||
FORMAT(U20_3BE),
|
||||
FORMAT(S18_3LE),
|
||||
FORMAT(S18_3BE),
|
||||
FORMAT(U18_3LE),
|
||||
FORMAT(U18_3BE),
|
||||
};
|
||||
|
||||
static const char *snd_pcm_format_descriptions[] = {
|
||||
|
|
@ -1229,6 +1241,18 @@ static const char *snd_pcm_format_descriptions[] = {
|
|||
FORMATD(MPEG, "MPEG"),
|
||||
FORMATD(GSM, "GSM"),
|
||||
FORMATD(SPECIAL, "Special"),
|
||||
FORMATD(S24_3LE, "Signed 24 bit Little Endian in 3bytes"),
|
||||
FORMATD(S24_3BE, "Signed 24 bit Big Endian in 3bytes"),
|
||||
FORMATD(U24_3LE, "Unsigned 24 bit Little Endian in 3bytes"),
|
||||
FORMATD(U24_3BE, "Unsigned 24 bit Big Endian in 3bytes"),
|
||||
FORMATD(S20_3LE, "Signed 20 bit Little Endian in 3bytes"),
|
||||
FORMATD(S20_3BE, "Signed 20 bit Big Endian in 3bytes"),
|
||||
FORMATD(U20_3LE, "Unsigned 20 bit Little Endian in 3bytes"),
|
||||
FORMATD(U20_3BE, "Unsigned 20 bit Big Endian in 3bytes"),
|
||||
FORMATD(S18_3LE, "Signed 18 bit Little Endian in 3bytes"),
|
||||
FORMATD(S18_3BE, "Signed 18 bit Big Endian in 3bytes"),
|
||||
FORMATD(U18_3LE, "Unsigned 18 bit Little Endian in 3bytes"),
|
||||
FORMATD(U18_3BE, "Unsigned 18 bit Big Endian in 3bytes"),
|
||||
};
|
||||
|
||||
static const char *snd_pcm_subformat_names[] = {
|
||||
|
|
@ -2129,6 +2153,13 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dump_one_param(snd_pcm_hw_params_t *params, unsigned int k, snd_output_t *out)
|
||||
{
|
||||
snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k));
|
||||
snd_pcm_hw_param_dump(params, k, out);
|
||||
snd_output_putc(out, '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dump a PCM hardware configuration space
|
||||
* \param params Configuration space
|
||||
|
|
@ -2138,11 +2169,10 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_
|
|||
int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out)
|
||||
{
|
||||
unsigned int k;
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++) {
|
||||
snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k));
|
||||
snd_pcm_hw_param_dump(params, k, out);
|
||||
snd_output_putc(out, '\n');
|
||||
}
|
||||
for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++)
|
||||
dump_one_param(params, k, out);
|
||||
for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
|
||||
dump_one_param(params, k, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -5433,7 +5463,7 @@ snd_pcm_uframes_t _snd_pcm_boundary(snd_pcm_t *pcm)
|
|||
return pcm->boundary;
|
||||
}
|
||||
|
||||
static const char *names[SND_PCM_HW_PARAM_LAST + 1] = {
|
||||
static const char *names[SND_PCM_HW_PARAM_LAST_INTERVAL + 1] = {
|
||||
[SND_PCM_HW_PARAM_FORMAT] = "format",
|
||||
[SND_PCM_HW_PARAM_CHANNELS] = "channels",
|
||||
[SND_PCM_HW_PARAM_RATE] = "rate",
|
||||
|
|
@ -5498,7 +5528,7 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
|||
for (k = 0; k < count; ++k) {
|
||||
unsigned int idx = fields[k].index;
|
||||
long v;
|
||||
assert(idx < SND_PCM_HW_PARAM_LAST);
|
||||
assert(idx < SND_PCM_HW_PARAM_LAST_INTERVAL);
|
||||
assert(names[idx]);
|
||||
if (strcmp(id, names[idx]) != 0)
|
||||
continue;
|
||||
|
|
|
|||
131
src/pcm/pcm_hw.c
131
src/pcm/pcm_hw.c
|
|
@ -54,8 +54,37 @@ const char *_snd_module_pcm_hw = "";
|
|||
#define F_SETSIG 10
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compatibility
|
||||
*/
|
||||
|
||||
struct sndrv_pcm_hw_params_old {
|
||||
unsigned int flags;
|
||||
unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
|
||||
SNDRV_PCM_HW_PARAM_ACCESS + 1];
|
||||
struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
|
||||
SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
|
||||
unsigned int rmask;
|
||||
unsigned int cmask;
|
||||
unsigned int info;
|
||||
unsigned int msbits;
|
||||
unsigned int rate_num;
|
||||
unsigned int rate_den;
|
||||
sndrv_pcm_uframes_t fifo_size;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
#define SND_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old)
|
||||
#define SND_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old)
|
||||
|
||||
#define SND_PCM_IOCTL_XRUN _IO('A', 0x48)
|
||||
|
||||
static int use_old_hw_params_ioctl(int fd, unsigned int cmd, snd_pcm_hw_params_t *params);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int fd;
|
||||
|
|
@ -72,7 +101,7 @@ typedef struct {
|
|||
|
||||
#define SNDRV_FILE_PCM_STREAM_PLAYBACK "/dev/snd/pcmC%iD%ip"
|
||||
#define SNDRV_FILE_PCM_STREAM_CAPTURE "/dev/snd/pcmC%iD%ic"
|
||||
#define SNDRV_PCM_VERSION_MAX SNDRV_PROTOCOL_VERSION(2, 0, 1)
|
||||
#define SNDRV_PCM_VERSION_MAX SNDRV_PROTOCOL_VERSION(2, 0, 2)
|
||||
|
||||
/* update appl_ptr with driver */
|
||||
#define UPDATE_SHADOW_PTR(hw) \
|
||||
|
|
@ -146,17 +175,25 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int hw_refine_call(snd_pcm_hw_t *pcm_hw, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
/* check for new hw_params structure; it's available from 2.0.2 version of PCM API */
|
||||
if (SNDRV_PROTOCOL_VERSION(2, 0, 2) <= pcm_hw->version)
|
||||
return ioctl(pcm_hw->fd, SNDRV_PCM_IOCTL_HW_REFINE, params);
|
||||
return use_old_hw_params_ioctl(pcm_hw->fd, SND_PCM_IOCTL_HW_REFINE_OLD, params);
|
||||
}
|
||||
|
||||
static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_hw_t *hw = pcm->private_data;
|
||||
int fd = hw->fd;
|
||||
if (hw->mmap_emulation) {
|
||||
int err = 0;
|
||||
snd_pcm_access_mask_t oldmask = *snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS);
|
||||
snd_pcm_access_mask_t mask = { 0 };
|
||||
snd_pcm_access_mask_t mask;
|
||||
const snd_mask_t *pmask;
|
||||
|
||||
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, params) < 0)
|
||||
snd_mask_empty(&mask);
|
||||
if (hw_refine_call(hw, params) < 0)
|
||||
err = -errno;
|
||||
if (err < 0) {
|
||||
snd_pcm_hw_params_t new = *params;
|
||||
|
|
@ -170,8 +207,8 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
if (snd_pcm_access_mask_empty(&mask))
|
||||
return err;
|
||||
pmask = snd_pcm_hw_param_get_mask(&new, SND_PCM_HW_PARAM_ACCESS);
|
||||
((snd_mask_t *)pmask)->bits = mask.bits;
|
||||
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, &new) < 0)
|
||||
*(snd_mask_t *)pmask = mask;
|
||||
if (hw_refine_call(hw, &new) < 0)
|
||||
return -errno;
|
||||
*params = new;
|
||||
}
|
||||
|
|
@ -203,7 +240,7 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, params) < 0) {
|
||||
if (hw_refine_call(hw, params) < 0) {
|
||||
// SYSERR("SNDRV_PCM_IOCTL_HW_REFINE failed");
|
||||
return -errno;
|
||||
}
|
||||
|
|
@ -212,13 +249,20 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int hw_params_call(snd_pcm_hw_t *pcm_hw, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
/* check for new hw_params structure; it's available from 2.0.2 version of PCM API */
|
||||
if (SNDRV_PROTOCOL_VERSION(2, 0, 2) <= pcm_hw->version)
|
||||
return ioctl(pcm_hw->fd, SNDRV_PCM_IOCTL_HW_PARAMS, params);
|
||||
return use_old_hw_params_ioctl(pcm_hw->fd, SND_PCM_IOCTL_HW_PARAMS_OLD, params);
|
||||
}
|
||||
|
||||
static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
||||
{
|
||||
snd_pcm_hw_t *hw = pcm->private_data;
|
||||
int fd = hw->fd;
|
||||
if (hw->mmap_emulation) {
|
||||
snd_pcm_hw_params_t old = *params;
|
||||
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, params) < 0) {
|
||||
if (hw_params_call(hw, params) < 0) {
|
||||
snd_pcm_access_mask_t oldmask;
|
||||
const snd_mask_t *pmask;
|
||||
|
||||
|
|
@ -237,13 +281,13 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
|||
default:
|
||||
goto _err;
|
||||
}
|
||||
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, params) < 0)
|
||||
if (hw_params_call(hw, params) < 0)
|
||||
goto _err;
|
||||
hw->mmap_shm = 1;
|
||||
*(snd_pcm_access_mask_t *)pmask = oldmask;
|
||||
}
|
||||
} else {
|
||||
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, params) < 0) {
|
||||
if (hw_params_call(hw, params) < 0) {
|
||||
_err:
|
||||
SYSERR("SNDRV_PCM_IOCTL_HW_PARAMS failed");
|
||||
return -errno;
|
||||
|
|
@ -964,3 +1008,68 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
|
|||
#ifndef DOC_HIDDEN
|
||||
SND_DLSYM_BUILD_VERSION(_snd_pcm_hw_open, SND_PCM_DLSYM_VERSION);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To be removed helpers, but keep binary compatibility at the time
|
||||
*/
|
||||
|
||||
#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
|
||||
#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
|
||||
|
||||
static void snd_pcm_hw_convert_from_old_params(snd_pcm_hw_params_t *params,
|
||||
struct sndrv_pcm_hw_params_old *oparams)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
memset(params, 0, sizeof(*params));
|
||||
params->flags = oparams->flags;
|
||||
for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++)
|
||||
params->masks[i].bits[0] = oparams->masks[i];
|
||||
memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
|
||||
params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
|
||||
params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
|
||||
params->info = oparams->info;
|
||||
params->msbits = oparams->msbits;
|
||||
params->rate_num = oparams->rate_num;
|
||||
params->rate_den = oparams->rate_den;
|
||||
params->fifo_size = oparams->fifo_size;
|
||||
}
|
||||
|
||||
static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old *oparams,
|
||||
snd_pcm_hw_params_t *params,
|
||||
unsigned int *cmask)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
memset(oparams, 0, sizeof(*oparams));
|
||||
oparams->flags = params->flags;
|
||||
for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++) {
|
||||
oparams->masks[i] = params->masks[i].bits[0];
|
||||
for (j = 1; j < sizeof(params->masks[i].bits) / sizeof(unsigned int); j++)
|
||||
if (params->masks[i].bits[j]) {
|
||||
*cmask |= 1 << i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
|
||||
oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
|
||||
oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
|
||||
oparams->info = params->info;
|
||||
oparams->msbits = params->msbits;
|
||||
oparams->rate_num = params->rate_num;
|
||||
oparams->rate_den = params->rate_den;
|
||||
oparams->fifo_size = params->fifo_size;
|
||||
}
|
||||
|
||||
static int use_old_hw_params_ioctl(int fd, unsigned int cmd, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
struct sndrv_pcm_hw_params_old oparams;
|
||||
unsigned int cmask = 0;
|
||||
int res;
|
||||
|
||||
snd_pcm_hw_convert_to_old_params(&oparams, params, &cmask);
|
||||
res = ioctl(fd, cmd, &oparams);
|
||||
snd_pcm_hw_convert_from_old_params(params, &oparams);
|
||||
params->cmask |= cmask;
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,11 +285,11 @@ static int snd_pcm_lfloat_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
dst_format = snd_pcm_hw_params_get_format(params);
|
||||
}
|
||||
if (snd_pcm_format_linear(src_format)) {
|
||||
lfloat->int32_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S32);
|
||||
lfloat->int32_idx = snd_pcm_linear_get32_index(src_format, SND_PCM_FORMAT_S32);
|
||||
lfloat->float32_idx = snd_pcm_lfloat_put_s32_index(dst_format);
|
||||
lfloat->func = snd_pcm_lfloat_convert_integer_float;
|
||||
} else {
|
||||
lfloat->int32_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S32, dst_format);
|
||||
lfloat->int32_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, dst_format);
|
||||
lfloat->float32_idx = snd_pcm_lfloat_get_s32_index(src_format);
|
||||
lfloat->func = snd_pcm_lfloat_convert_float_integer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ const char *_snd_module_pcm_linear = "";
|
|||
typedef struct {
|
||||
/* This field need to be the first */
|
||||
snd_pcm_plugin_t plug;
|
||||
unsigned int use_getput;
|
||||
unsigned int conv_idx;
|
||||
unsigned int get_idx, put_idx;
|
||||
snd_pcm_format_t sformat;
|
||||
} snd_pcm_linear_t;
|
||||
#endif
|
||||
|
|
@ -74,10 +76,9 @@ int snd_pcm_linear_convert_index(snd_pcm_format_t src_format,
|
|||
|
||||
int snd_pcm_linear_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
|
||||
{
|
||||
int sign, width, endian;
|
||||
int sign, width, pwidth, endian;
|
||||
sign = (snd_pcm_format_signed(src_format) !=
|
||||
snd_pcm_format_signed(dst_format));
|
||||
width = snd_pcm_format_width(src_format) / 8 - 1;
|
||||
#ifdef SND_LITTLE_ENDIAN
|
||||
endian = snd_pcm_format_big_endian(src_format);
|
||||
#else
|
||||
|
|
@ -85,8 +86,29 @@ int snd_pcm_linear_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_f
|
|||
#endif
|
||||
if (endian < 0)
|
||||
endian = 0;
|
||||
pwidth = snd_pcm_format_physical_width(src_format);
|
||||
width = snd_pcm_format_width(src_format);
|
||||
if (pwidth == 24) {
|
||||
switch (width) {
|
||||
case 24:
|
||||
width = 0; break;
|
||||
case 20:
|
||||
width = 1; break;
|
||||
case 18:
|
||||
default:
|
||||
width = 2; break;
|
||||
}
|
||||
return width * 4 + endian * 2 + sign + 16;
|
||||
} else {
|
||||
width = width / 8 - 1;
|
||||
return width * 4 + endian * 2 + sign;
|
||||
}
|
||||
}
|
||||
|
||||
int snd_pcm_linear_get32_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
|
||||
{
|
||||
return snd_pcm_linear_get_index(src_format, dst_format);
|
||||
}
|
||||
|
||||
int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
|
||||
{
|
||||
|
|
@ -104,6 +126,37 @@ int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_f
|
|||
return width * 4 + endian * 2 + sign;
|
||||
}
|
||||
|
||||
int snd_pcm_linear_put32_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
|
||||
{
|
||||
int sign, width, pwidth, endian;
|
||||
sign = (snd_pcm_format_signed(src_format) !=
|
||||
snd_pcm_format_signed(dst_format));
|
||||
#ifdef SND_LITTLE_ENDIAN
|
||||
endian = snd_pcm_format_big_endian(dst_format);
|
||||
#else
|
||||
endian = snd_pcm_format_little_endian(dst_format);
|
||||
#endif
|
||||
if (endian < 0)
|
||||
endian = 0;
|
||||
pwidth = snd_pcm_format_physical_width(dst_format);
|
||||
width = snd_pcm_format_width(dst_format);
|
||||
if (pwidth == 24) {
|
||||
switch (width) {
|
||||
case 24:
|
||||
width = 0; break;
|
||||
case 20:
|
||||
width = 1; break;
|
||||
case 18:
|
||||
default:
|
||||
width = 2; break;
|
||||
}
|
||||
return width * 4 + endian * 2 + sign + 16;
|
||||
} else {
|
||||
width = width / 8 - 1;
|
||||
return width * 4 + endian * 2 + sign;
|
||||
}
|
||||
}
|
||||
|
||||
void snd_pcm_linear_convert(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
|
||||
unsigned int channels, snd_pcm_uframes_t frames,
|
||||
|
|
@ -138,6 +191,42 @@ void snd_pcm_linear_convert(const snd_pcm_channel_area_t *dst_areas, snd_pcm_ufr
|
|||
}
|
||||
}
|
||||
|
||||
void snd_pcm_linear_getput(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
|
||||
unsigned int channels, snd_pcm_uframes_t frames,
|
||||
unsigned int get_idx, unsigned int put_idx)
|
||||
{
|
||||
#define CONV24_LABELS
|
||||
#include "plugin_ops.h"
|
||||
#undef CONV24_LABELS
|
||||
void *get = get32_labels[get_idx];
|
||||
void *put = put32_labels[put_idx];
|
||||
unsigned int channel;
|
||||
u_int32_t sample = 0;
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
const char *src;
|
||||
char *dst;
|
||||
int src_step, dst_step;
|
||||
snd_pcm_uframes_t frames1;
|
||||
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
|
||||
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
|
||||
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);
|
||||
frames1 = frames;
|
||||
while (frames1-- > 0) {
|
||||
goto *get;
|
||||
#define CONV24_END after
|
||||
#include "plugin_ops.h"
|
||||
#undef CONV24_END
|
||||
after:
|
||||
src += src_step;
|
||||
dst += dst_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DOC_HIDDEN */
|
||||
|
||||
static int snd_pcm_linear_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
|
||||
|
|
@ -228,12 +317,24 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
snd_pcm_plugin_hw_params_slave);
|
||||
if (err < 0)
|
||||
return err;
|
||||
linear->use_getput = (snd_pcm_format_physical_width(snd_pcm_hw_params_get_format(params)) == 24 ||
|
||||
snd_pcm_format_physical_width(linear->sformat) == 24);
|
||||
if (linear->use_getput) {
|
||||
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||
linear->get_idx = snd_pcm_linear_get32_index(snd_pcm_hw_params_get_format(params), SND_PCM_FORMAT_S32);
|
||||
linear->put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, linear->sformat);
|
||||
} else {
|
||||
linear->get_idx = snd_pcm_linear_get32_index(linear->sformat, SND_PCM_FORMAT_S32);
|
||||
linear->put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, snd_pcm_hw_params_get_format(params));
|
||||
}
|
||||
} else {
|
||||
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
|
||||
linear->conv_idx = snd_pcm_linear_convert_index(snd_pcm_hw_params_get_format(params),
|
||||
linear->sformat);
|
||||
else
|
||||
linear->conv_idx = snd_pcm_linear_convert_index(linear->sformat,
|
||||
snd_pcm_hw_params_get_format(params));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +350,12 @@ snd_pcm_linear_write_areas(snd_pcm_t *pcm,
|
|||
snd_pcm_linear_t *linear = pcm->private_data;
|
||||
if (size > *slave_sizep)
|
||||
size = *slave_sizep;
|
||||
if (linear->use_getput)
|
||||
snd_pcm_linear_getput(slave_areas, slave_offset,
|
||||
areas, offset,
|
||||
pcm->channels, size,
|
||||
linear->get_idx, linear->put_idx);
|
||||
else
|
||||
snd_pcm_linear_convert(slave_areas, slave_offset,
|
||||
areas, offset,
|
||||
pcm->channels, size, linear->conv_idx);
|
||||
|
|
@ -268,6 +375,12 @@ snd_pcm_linear_read_areas(snd_pcm_t *pcm,
|
|||
snd_pcm_linear_t *linear = pcm->private_data;
|
||||
if (size > *slave_sizep)
|
||||
size = *slave_sizep;
|
||||
if (linear->use_getput)
|
||||
snd_pcm_linear_getput(areas, offset,
|
||||
slave_areas, slave_offset,
|
||||
pcm->channels, size,
|
||||
linear->get_idx, linear->put_idx);
|
||||
else
|
||||
snd_pcm_linear_convert(areas, offset,
|
||||
slave_areas, slave_offset,
|
||||
pcm->channels, size, linear->conv_idx);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <limits.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#define _snd_mask sndrv_mask
|
||||
#define _snd_pcm_access_mask _snd_mask
|
||||
#define _snd_pcm_format_mask _snd_mask
|
||||
#define _snd_pcm_subformat_mask _snd_mask
|
||||
|
|
@ -57,7 +58,6 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
|
|||
#define SND_PCM_HW_PARAM_BUFFER_BYTES SNDRV_PCM_HW_PARAM_BUFFER_BYTES
|
||||
#define SND_PCM_HW_PARAM_TICK_TIME SNDRV_PCM_HW_PARAM_TICK_TIME
|
||||
#define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL
|
||||
#define SND_PCM_HW_PARAM_LAST SNDRV_PCM_HW_PARAM_LAST
|
||||
#define SND_PCM_HW_PARAMS_RUNTIME SNDRV_PCM_HW_PARAMS_RUNTIME
|
||||
#define SND_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_LAST_MASK
|
||||
#define SND_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_FIRST_MASK
|
||||
|
|
@ -568,24 +568,24 @@ int snd_pcm_conf_generic_id(const char *id);
|
|||
#define SND_PCM_HW_PARBIT_TICK_TIME (1U << SND_PCM_HW_PARAM_TICK_TIME)
|
||||
|
||||
|
||||
#define SND_PCM_ACCBIT_MMAP ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||
#define SND_PCM_ACCBIT_MMAP { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_MMAP_COMPLEX))
|
||||
#define SND_PCM_ACCBIT_MMAPI (1U << SND_PCM_ACCESS_MMAP_INTERLEAVED)
|
||||
#define SND_PCM_ACCBIT_MMAPN (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED)
|
||||
#define SND_PCM_ACCBIT_MMAPC (1U << SND_PCM_ACCESS_MMAP_COMPLEX)
|
||||
(1U << SND_PCM_ACCESS_MMAP_COMPLEX)) }
|
||||
#define SND_PCM_ACCBIT_MMAPI { (1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) }
|
||||
#define SND_PCM_ACCBIT_MMAPN { (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) }
|
||||
#define SND_PCM_ACCBIT_MMAPC { (1U << SND_PCM_ACCESS_MMAP_COMPLEX) }
|
||||
|
||||
#define SND_PCM_ACCBIT_SHM ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||
#define SND_PCM_ACCBIT_SHM { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_RW_INTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_RW_NONINTERLEAVED))
|
||||
#define SND_PCM_ACCBIT_SHMI ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_RW_INTERLEAVED))
|
||||
#define SND_PCM_ACCBIT_SHMN ((1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_RW_NONINTERLEAVED))
|
||||
(1U << SND_PCM_ACCESS_RW_NONINTERLEAVED)) }
|
||||
#define SND_PCM_ACCBIT_SHMI { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_RW_INTERLEAVED)) }
|
||||
#define SND_PCM_ACCBIT_SHMN { ((1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
|
||||
(1U << SND_PCM_ACCESS_RW_NONINTERLEAVED)) }
|
||||
|
||||
#define SND_PCM_FMTBIT_LINEAR \
|
||||
((1U << SND_PCM_FORMAT_S8) | \
|
||||
{ ((1U << SND_PCM_FORMAT_S8) | \
|
||||
(1U << SND_PCM_FORMAT_U8) | \
|
||||
(1U << SND_PCM_FORMAT_S16_LE) | \
|
||||
(1U << SND_PCM_FORMAT_S16_BE) | \
|
||||
|
|
@ -598,10 +598,23 @@ int snd_pcm_conf_generic_id(const char *id);
|
|||
(1U << SND_PCM_FORMAT_S32_LE) | \
|
||||
(1U << SND_PCM_FORMAT_S32_BE) | \
|
||||
(1U << SND_PCM_FORMAT_U32_LE) | \
|
||||
(1U << SND_PCM_FORMAT_U32_BE))
|
||||
(1U << SND_PCM_FORMAT_U32_BE)), \
|
||||
((1U << (SND_PCM_FORMAT_S24_3LE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_U24_3LE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_S24_3BE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_U24_3BE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_S20_3LE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_U20_3LE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_S20_3BE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_U20_3BE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_S18_3LE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_U18_3LE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_S18_3BE - 32)) | \
|
||||
(1U << (SND_PCM_FORMAT_U18_3BE - 32))) }
|
||||
|
||||
|
||||
#define SND_PCM_FMTBIT_FLOAT \
|
||||
((1U << SND_PCM_FORMAT_FLOAT_LE) | \
|
||||
{ ((1U << SND_PCM_FORMAT_FLOAT_LE) | \
|
||||
(1U << SND_PCM_FORMAT_FLOAT_BE) | \
|
||||
(1U << SND_PCM_FORMAT_FLOAT64_LE) | \
|
||||
(1U << SND_PCM_FORMAT_FLOAT64_BE))
|
||||
(1U << SND_PCM_FORMAT_FLOAT64_BE)) }
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_S24_BE:
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
case SNDRV_PCM_FORMAT_S32_BE:
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
case SNDRV_PCM_FORMAT_S24_3BE:
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case SNDRV_PCM_FORMAT_S20_3BE:
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
case SNDRV_PCM_FORMAT_S18_3BE:
|
||||
return 1;
|
||||
case SNDRV_PCM_FORMAT_U8:
|
||||
case SNDRV_PCM_FORMAT_U16_LE:
|
||||
|
|
@ -50,6 +56,12 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_U24_BE:
|
||||
case SNDRV_PCM_FORMAT_U32_LE:
|
||||
case SNDRV_PCM_FORMAT_U32_BE:
|
||||
case SNDRV_PCM_FORMAT_U24_3LE:
|
||||
case SNDRV_PCM_FORMAT_U24_3BE:
|
||||
case SNDRV_PCM_FORMAT_U20_3LE:
|
||||
case SNDRV_PCM_FORMAT_U20_3BE:
|
||||
case SNDRV_PCM_FORMAT_U18_3LE:
|
||||
case SNDRV_PCM_FORMAT_U18_3BE:
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -116,6 +128,12 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_FLOAT_LE:
|
||||
case SNDRV_PCM_FORMAT_FLOAT64_LE:
|
||||
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
case SNDRV_PCM_FORMAT_U24_3LE:
|
||||
case SNDRV_PCM_FORMAT_U20_3LE:
|
||||
case SNDRV_PCM_FORMAT_U18_3LE:
|
||||
return 1;
|
||||
case SNDRV_PCM_FORMAT_S16_BE:
|
||||
case SNDRV_PCM_FORMAT_U16_BE:
|
||||
|
|
@ -126,6 +144,12 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_FLOAT_BE:
|
||||
case SNDRV_PCM_FORMAT_FLOAT64_BE:
|
||||
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
|
||||
case SNDRV_PCM_FORMAT_S24_3BE:
|
||||
case SNDRV_PCM_FORMAT_S20_3BE:
|
||||
case SNDRV_PCM_FORMAT_S18_3BE:
|
||||
case SNDRV_PCM_FORMAT_U24_3BE:
|
||||
case SNDRV_PCM_FORMAT_U20_3BE:
|
||||
case SNDRV_PCM_FORMAT_U18_3BE:
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -177,10 +201,24 @@ int snd_pcm_format_width(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_U16_LE:
|
||||
case SNDRV_PCM_FORMAT_U16_BE:
|
||||
return 16;
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
case SNDRV_PCM_FORMAT_S18_3BE:
|
||||
case SNDRV_PCM_FORMAT_U18_3LE:
|
||||
case SNDRV_PCM_FORMAT_U18_3BE:
|
||||
return 18;
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case SNDRV_PCM_FORMAT_S20_3BE:
|
||||
case SNDRV_PCM_FORMAT_U20_3LE:
|
||||
case SNDRV_PCM_FORMAT_U20_3BE:
|
||||
return 20;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case SNDRV_PCM_FORMAT_S24_BE:
|
||||
case SNDRV_PCM_FORMAT_U24_LE:
|
||||
case SNDRV_PCM_FORMAT_U24_BE:
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
case SNDRV_PCM_FORMAT_S24_3BE:
|
||||
case SNDRV_PCM_FORMAT_U24_3LE:
|
||||
case SNDRV_PCM_FORMAT_U24_3BE:
|
||||
return 24;
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
case SNDRV_PCM_FORMAT_S32_BE:
|
||||
|
|
@ -221,6 +259,19 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_U16_LE:
|
||||
case SNDRV_PCM_FORMAT_U16_BE:
|
||||
return 16;
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
case SNDRV_PCM_FORMAT_S18_3BE:
|
||||
case SNDRV_PCM_FORMAT_U18_3LE:
|
||||
case SNDRV_PCM_FORMAT_U18_3BE:
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case SNDRV_PCM_FORMAT_S20_3BE:
|
||||
case SNDRV_PCM_FORMAT_U20_3LE:
|
||||
case SNDRV_PCM_FORMAT_U20_3BE:
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
case SNDRV_PCM_FORMAT_S24_3BE:
|
||||
case SNDRV_PCM_FORMAT_U24_3LE:
|
||||
case SNDRV_PCM_FORMAT_U24_3BE:
|
||||
return 24;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case SNDRV_PCM_FORMAT_S24_BE:
|
||||
case SNDRV_PCM_FORMAT_U24_LE:
|
||||
|
|
@ -264,6 +315,19 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
|
|||
case SNDRV_PCM_FORMAT_U16_LE:
|
||||
case SNDRV_PCM_FORMAT_U16_BE:
|
||||
return samples * 2;
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
case SNDRV_PCM_FORMAT_S18_3BE:
|
||||
case SNDRV_PCM_FORMAT_U18_3LE:
|
||||
case SNDRV_PCM_FORMAT_U18_3BE:
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case SNDRV_PCM_FORMAT_S20_3BE:
|
||||
case SNDRV_PCM_FORMAT_U20_3LE:
|
||||
case SNDRV_PCM_FORMAT_U20_3BE:
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
case SNDRV_PCM_FORMAT_S24_3BE:
|
||||
case SNDRV_PCM_FORMAT_U24_3LE:
|
||||
case SNDRV_PCM_FORMAT_U24_3BE:
|
||||
return samples * 3;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case SNDRV_PCM_FORMAT_S24_BE:
|
||||
case SNDRV_PCM_FORMAT_U24_LE:
|
||||
|
|
@ -309,6 +373,12 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_S24_BE:
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
case SNDRV_PCM_FORMAT_S32_BE:
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
case SNDRV_PCM_FORMAT_S24_3BE:
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case SNDRV_PCM_FORMAT_S20_3BE:
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
case SNDRV_PCM_FORMAT_S18_3BE:
|
||||
return 0;
|
||||
case SNDRV_PCM_FORMAT_U8:
|
||||
return 0x8080808080808080ULL;
|
||||
|
|
@ -339,6 +409,15 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
|
|||
case SNDRV_PCM_FORMAT_U32_BE:
|
||||
return 0x8000000080000000ULL;
|
||||
#endif
|
||||
case SNDRV_PCM_FORMAT_U24_3LE:
|
||||
case SNDRV_PCM_FORMAT_U24_3BE:
|
||||
return 0x0000800000800000ULL;
|
||||
case SNDRV_PCM_FORMAT_U20_3LE:
|
||||
case SNDRV_PCM_FORMAT_U20_3BE:
|
||||
return 0x0000080000080000ULL;
|
||||
case SNDRV_PCM_FORMAT_U18_3LE:
|
||||
case SNDRV_PCM_FORMAT_U18_3BE:
|
||||
return 0x0000020000020000ULL;
|
||||
case SNDRV_PCM_FORMAT_FLOAT_LE:
|
||||
{
|
||||
union {
|
||||
|
|
@ -470,20 +549,45 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
|
|||
}
|
||||
case 16: {
|
||||
u_int16_t silence = snd_pcm_format_silence_64(format);
|
||||
if (! silence)
|
||||
memset(data, 0, samples * 2);
|
||||
else {
|
||||
while (samples-- > 0)
|
||||
*((u_int16_t *)data)++ = silence;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
u_int32_t silence = snd_pcm_format_silence_64(format);
|
||||
if (! silence)
|
||||
memset(data, 0, samples * 3);
|
||||
else {
|
||||
/* FIXME: rewrite in the more better way.. */
|
||||
int i;
|
||||
while (samples-- > 0) {
|
||||
for (i = 0; i < 3; i++)
|
||||
*((u_int8_t *)data)++ = silence >> (i * 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
case 32: {
|
||||
u_int32_t silence = snd_pcm_format_silence_64(format);
|
||||
if (! silence)
|
||||
memset(data, 0, samples * 4);
|
||||
else {
|
||||
while (samples-- > 0)
|
||||
*((u_int32_t *)data)++ = silence;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 64: {
|
||||
u_int64_t silence = snd_pcm_format_silence_64(format);
|
||||
if (! silence)
|
||||
memset(data, 0, samples * 8);
|
||||
else {
|
||||
while (samples-- > 0)
|
||||
*((u_int64_t *)data)++ = silence;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -512,14 +616,46 @@ static int linear_formats[4*2*2] = {
|
|||
SNDRV_PCM_FORMAT_U32_BE
|
||||
};
|
||||
|
||||
static int linear24_formats[3*2*2] = {
|
||||
SNDRV_PCM_FORMAT_S24_3LE,
|
||||
SNDRV_PCM_FORMAT_S24_3BE,
|
||||
SNDRV_PCM_FORMAT_U24_3LE,
|
||||
SNDRV_PCM_FORMAT_U24_3BE,
|
||||
SNDRV_PCM_FORMAT_S20_3LE,
|
||||
SNDRV_PCM_FORMAT_S20_3BE,
|
||||
SNDRV_PCM_FORMAT_U20_3LE,
|
||||
SNDRV_PCM_FORMAT_U20_3BE,
|
||||
SNDRV_PCM_FORMAT_S18_3LE,
|
||||
SNDRV_PCM_FORMAT_S18_3BE,
|
||||
SNDRV_PCM_FORMAT_U18_3LE,
|
||||
SNDRV_PCM_FORMAT_U18_3BE,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Compose a PCM sample linear format
|
||||
* \param width Nominal bits per sample
|
||||
* \param pwidth Physical bit width of the format
|
||||
* \param unsignd Sign: 0 signed, 1 unsigned
|
||||
* \return big_endian Endian: 0 little endian, 1 big endian
|
||||
*/
|
||||
snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
|
||||
snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian)
|
||||
{
|
||||
if (pwidth == 24) {
|
||||
switch (width) {
|
||||
case 24:
|
||||
width = 0;
|
||||
break;
|
||||
case 20:
|
||||
width = 1;
|
||||
break;
|
||||
case 18:
|
||||
width = 2;
|
||||
break;
|
||||
default:
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
return ((int(*)[2][2])linear24_formats)[width][!!unsignd][!!big_endian];
|
||||
} else {
|
||||
switch (width) {
|
||||
case 8:
|
||||
width = 0;
|
||||
|
|
@ -538,3 +674,4 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_end
|
|||
}
|
||||
return ((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
|
|||
{
|
||||
unsigned int k;
|
||||
memset(params, 0, sizeof(*params));
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
|
||||
for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++)
|
||||
_snd_pcm_hw_param_any(params, k);
|
||||
for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
|
||||
_snd_pcm_hw_param_any(params, k);
|
||||
params->info = ~0U;
|
||||
}
|
||||
|
|
@ -1144,7 +1146,7 @@ const char *snd_pcm_hw_param_names[] = {
|
|||
|
||||
const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t param)
|
||||
{
|
||||
assert(param <= SND_PCM_HW_PARAM_LAST);
|
||||
assert(param <= SND_PCM_HW_PARAM_LAST_INTERVAL);
|
||||
return snd_pcm_hw_param_names[param];
|
||||
}
|
||||
|
||||
|
|
@ -1250,7 +1252,7 @@ void snd_pcm_hw_strategy_simple_free(snd_pcm_hw_strategy_t *strategy)
|
|||
{
|
||||
snd_pcm_hw_strategy_simple_t *pars = strategy->private_data;
|
||||
int k;
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; ++k) {
|
||||
if (pars[k].valid && pars[k].free)
|
||||
pars[k].free(&pars[k]);
|
||||
}
|
||||
|
|
@ -1266,7 +1268,7 @@ int snd_pcm_hw_strategy_simple_choose_param(const snd_pcm_hw_params_t *params,
|
|||
const snd_pcm_hw_strategy_simple_t *pars = strategy->private_data;
|
||||
unsigned int min_choices = UINT_MAX;
|
||||
unsigned int min_order = UINT_MAX;
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; ++var) {
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST_INTERVAL; ++var) {
|
||||
const snd_pcm_hw_strategy_simple_t *p = &pars[var];
|
||||
unsigned int choices;
|
||||
if (!p->valid)
|
||||
|
|
@ -1306,7 +1308,7 @@ int snd_pcm_hw_strategy_simple_min_badness(const snd_pcm_hw_params_t *params,
|
|||
snd_pcm_hw_param_t var;
|
||||
unsigned int badness = 0;
|
||||
const snd_pcm_hw_strategy_simple_t *pars = strategy->private_data;
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; ++var) {
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST_INTERVAL; ++var) {
|
||||
unsigned int b;
|
||||
if (!pars[var].valid)
|
||||
continue;
|
||||
|
|
@ -1418,7 +1420,7 @@ int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
|
|||
snd_pcm_hw_strategy_simple_t *data;
|
||||
snd_pcm_hw_strategy_t *s;
|
||||
assert(strategyp);
|
||||
data = calloc(SND_PCM_HW_PARAM_LAST + 1, sizeof(*data));
|
||||
data = calloc(SND_PCM_HW_PARAM_LAST_INTERVAL + 1, sizeof(*data));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
s = calloc(1, sizeof(*s));
|
||||
|
|
@ -1446,7 +1448,7 @@ int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy,
|
|||
snd_pcm_hw_strategy_simple_t *s = strategy->private_data;
|
||||
snd_pcm_hw_strategy_simple_near_t *data;
|
||||
assert(strategy);
|
||||
assert(var <= SND_PCM_HW_PARAM_LAST);
|
||||
assert(var <= SND_PCM_HW_PARAM_LAST_INTERVAL);
|
||||
assert(!s->valid);
|
||||
data = calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
|
|
@ -1472,7 +1474,7 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy,
|
|||
snd_pcm_hw_strategy_simple_t *s = strategy->private_data;
|
||||
snd_pcm_hw_strategy_simple_choices_t *data;
|
||||
assert(strategy);
|
||||
assert(var <= SND_PCM_HW_PARAM_LAST);
|
||||
assert(var <= SND_PCM_HW_PARAM_LAST_INTERVAL);
|
||||
assert(!s->valid);
|
||||
data = calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
|
|
@ -1499,7 +1501,7 @@ int snd_pcm_hw_params_try_explain_failure1(snd_pcm_t *pcm,
|
|||
snd_pcm_hw_params_t i;
|
||||
if (depth < 1)
|
||||
return -ENOENT;
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) {
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST_INTERVAL; var++) {
|
||||
int err;
|
||||
i = *success;
|
||||
_snd_pcm_hw_param_copy(&i, var, fail);
|
||||
|
|
@ -1526,7 +1528,7 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
|
|||
snd_pcm_hw_param_t var;
|
||||
int done = 0;
|
||||
assert(pcm && fail);
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) {
|
||||
for (var = 0; var <= SND_PCM_HW_PARAM_LAST_INTERVAL; var++) {
|
||||
if (!snd_pcm_hw_param_empty(fail, var))
|
||||
continue;
|
||||
snd_output_printf(out, "%s is empty\n", snd_pcm_hw_param_name(var));
|
||||
|
|
@ -1805,13 +1807,13 @@ static snd_pcm_hw_rule_t refine_rules[] = {
|
|||
|
||||
static snd_mask_t refine_masks[SND_PCM_HW_PARAM_LAST_MASK - SND_PCM_HW_PARAM_FIRST_MASK + 1] = {
|
||||
[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK] = {
|
||||
bits: 0x1f,
|
||||
bits: { 0x1f },
|
||||
},
|
||||
[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK] = {
|
||||
bits: 0x81ffffff,
|
||||
bits: { 0x81ffffff, 0xfff},
|
||||
},
|
||||
[SND_PCM_HW_PARAM_SUBFORMAT - SND_PCM_HW_PARAM_FIRST_MASK] = {
|
||||
bits: 0x1,
|
||||
bits: { 0x1 },
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -1873,7 +1875,7 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
|
|||
unsigned int k;
|
||||
snd_interval_t *i;
|
||||
unsigned int rstamps[RULES];
|
||||
unsigned int vstamps[SND_PCM_HW_PARAM_LAST + 1];
|
||||
unsigned int vstamps[SND_PCM_HW_PARAM_LAST_INTERVAL + 1];
|
||||
unsigned int stamp = 2;
|
||||
int changed, again;
|
||||
#ifdef RULES_DEBUG
|
||||
|
|
@ -1905,7 +1907,7 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
|
|||
|
||||
for (k = 0; k < RULES; k++)
|
||||
rstamps[k] = 0;
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
|
||||
vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0;
|
||||
do {
|
||||
again = 0;
|
||||
|
|
@ -1978,7 +1980,7 @@ int _snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
|
|||
{
|
||||
int changed, err = 0;
|
||||
unsigned int k;
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
|
||||
for (k = 0; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; ++k) {
|
||||
if (!(vars & (1 << k)))
|
||||
continue;
|
||||
changed = _snd_pcm_hw_param_refine(params, k, src);
|
||||
|
|
|
|||
|
|
@ -145,6 +145,39 @@ static snd_pcm_format_t linear_preferred_formats[] = {
|
|||
SND_PCM_FORMAT_S24_LE,
|
||||
SND_PCM_FORMAT_U24_LE,
|
||||
#endif
|
||||
#ifdef SND_LITTLE_ENDIAN
|
||||
SND_PCM_FORMAT_S24_3LE,
|
||||
SND_PCM_FORMAT_U24_3LE,
|
||||
SND_PCM_FORMAT_S24_3BE,
|
||||
SND_PCM_FORMAT_U24_3BE,
|
||||
#else
|
||||
SND_PCM_FORMAT_S24_3BE,
|
||||
SND_PCM_FORMAT_U24_3BE,
|
||||
SND_PCM_FORMAT_S24_3LE,
|
||||
SND_PCM_FORMAT_U24_3LE,
|
||||
#endif
|
||||
#ifdef SND_LITTLE_ENDIAN
|
||||
SND_PCM_FORMAT_S20_3LE,
|
||||
SND_PCM_FORMAT_U20_3LE,
|
||||
SND_PCM_FORMAT_S20_3BE,
|
||||
SND_PCM_FORMAT_U20_3BE,
|
||||
#else
|
||||
SND_PCM_FORMAT_S20_3BE,
|
||||
SND_PCM_FORMAT_U20_3BE,
|
||||
SND_PCM_FORMAT_S20_3LE,
|
||||
SND_PCM_FORMAT_U20_3LE,
|
||||
#endif
|
||||
#ifdef SND_LITTLE_ENDIAN
|
||||
SND_PCM_FORMAT_S18_3LE,
|
||||
SND_PCM_FORMAT_U18_3LE,
|
||||
SND_PCM_FORMAT_S18_3BE,
|
||||
SND_PCM_FORMAT_U18_3BE,
|
||||
#else
|
||||
SND_PCM_FORMAT_S18_3BE,
|
||||
SND_PCM_FORMAT_U18_3BE,
|
||||
SND_PCM_FORMAT_S18_3LE,
|
||||
SND_PCM_FORMAT_U18_3LE,
|
||||
#endif
|
||||
};
|
||||
|
||||
static snd_pcm_format_t nonlinear_preferred_formats[] = {
|
||||
|
|
@ -167,9 +200,39 @@ static snd_pcm_format_t float_preferred_formats[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static char linear_format_widths[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
||||
0, 1, 0, 1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
||||
};
|
||||
|
||||
static int check_linear_format(const snd_pcm_format_mask_t *format_mask, int wid, int sgn, int ed)
|
||||
{
|
||||
int e, s;
|
||||
if (! linear_format_widths[wid - 1])
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
for (e = 0; e < 2; e++) {
|
||||
for (s = 0; s < 2; s++) {
|
||||
int pw = ((wid + 7) / 8) * 8;
|
||||
for (; pw <= 32; pw += 8) {
|
||||
snd_pcm_format_t f;
|
||||
f = snd_pcm_build_linear_format(wid, pw, sgn, ed);
|
||||
if (f != SND_PCM_FORMAT_UNKNOWN &&
|
||||
snd_pcm_format_mask_test(format_mask, f))
|
||||
return f;
|
||||
}
|
||||
sgn = !sgn;
|
||||
}
|
||||
ed = !ed;
|
||||
}
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const snd_pcm_format_mask_t *format_mask)
|
||||
{
|
||||
int w, u, e, wid, w1, dw;
|
||||
int w, w1, u, e;
|
||||
snd_pcm_format_t f;
|
||||
snd_pcm_format_mask_t lin = { SND_PCM_FMTBIT_LINEAR };
|
||||
snd_pcm_format_mask_t fl = { SND_PCM_FMTBIT_FLOAT };
|
||||
if (snd_pcm_format_mask_test(format_mask, format))
|
||||
|
|
@ -228,28 +291,15 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
|
|||
u = snd_pcm_format_unsigned(format);
|
||||
e = snd_pcm_format_big_endian(format);
|
||||
}
|
||||
w1 = w;
|
||||
dw = 8;
|
||||
for (wid = 0; wid < 4; ++wid) {
|
||||
int end, e1 = e;
|
||||
for (end = 0; end < 2; ++end) {
|
||||
int sgn, u1 = u;
|
||||
for (sgn = 0; sgn < 2; ++sgn) {
|
||||
snd_pcm_format_t f;
|
||||
f = snd_pcm_build_linear_format(w1, u1, e1);
|
||||
assert(f != SND_PCM_FORMAT_UNKNOWN);
|
||||
if (snd_pcm_format_mask_test(format_mask, f))
|
||||
for (w1 = w; w1 <= 32; w1++) {
|
||||
f = check_linear_format(format_mask, w1, u, e);
|
||||
if (f != SND_PCM_FORMAT_UNKNOWN)
|
||||
return f;
|
||||
u1 = !u1;
|
||||
}
|
||||
e1 = !e1;
|
||||
}
|
||||
if (w1 < 32)
|
||||
w1 += dw;
|
||||
else {
|
||||
w1 = w - 8;
|
||||
dw = -8;
|
||||
}
|
||||
for (w1 = w - 1; w1 > 0; w1--) {
|
||||
f = check_linear_format(format_mask, w1, u, e);
|
||||
if (f != SND_PCM_FORMAT_UNKNOWN)
|
||||
return f;
|
||||
}
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,12 +105,18 @@ snd_pcm_sframes_t snd_pcm_plugin_undo_write_generic
|
|||
|
||||
int snd_pcm_linear_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
|
||||
int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
|
||||
int snd_pcm_linear_get32_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
|
||||
int snd_pcm_linear_put32_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
|
||||
int snd_pcm_linear_convert_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
|
||||
|
||||
void snd_pcm_linear_convert(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
|
||||
unsigned int channels, snd_pcm_uframes_t frames,
|
||||
unsigned int convidx);
|
||||
void snd_pcm_linear_getput(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
|
||||
unsigned int channels, snd_pcm_uframes_t frames,
|
||||
unsigned int get_idx, unsigned int put_idx);
|
||||
void snd_pcm_alaw_decode(const snd_pcm_channel_area_t *dst_areas,
|
||||
snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ typedef struct {
|
|||
unsigned int get_idx;
|
||||
unsigned int put_idx;
|
||||
unsigned int conv_idx;
|
||||
int use_getput;
|
||||
unsigned int src_size;
|
||||
snd_pcm_format_t dst_sfmt;
|
||||
unsigned int ndsts;
|
||||
|
|
@ -160,6 +161,53 @@ static void snd_pcm_route_convert1_one(const snd_pcm_channel_area_t *dst_area,
|
|||
}
|
||||
}
|
||||
|
||||
static void snd_pcm_route_convert1_one_getput(const snd_pcm_channel_area_t *dst_area,
|
||||
snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas,
|
||||
snd_pcm_uframes_t src_offset,
|
||||
snd_pcm_uframes_t frames,
|
||||
const snd_pcm_route_ttable_dst_t* ttable,
|
||||
const snd_pcm_route_params_t *params)
|
||||
{
|
||||
#define CONV24_LABELS
|
||||
#include "plugin_ops.h"
|
||||
#undef CONV24_LABELS
|
||||
void *get, *put;
|
||||
const snd_pcm_channel_area_t *src_area = 0;
|
||||
unsigned int srcidx;
|
||||
const char *src;
|
||||
char *dst;
|
||||
int src_step, dst_step;
|
||||
u_int32_t sample = 0;
|
||||
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
|
||||
src_area = &src_areas[ttable->srcs[srcidx].channel];
|
||||
if (src_area->addr != NULL)
|
||||
break;
|
||||
}
|
||||
if (srcidx == ttable->nsrcs) {
|
||||
snd_pcm_route_convert1_zero(dst_area, dst_offset,
|
||||
src_areas, src_offset,
|
||||
frames, ttable, params);
|
||||
return;
|
||||
}
|
||||
|
||||
get = get32_labels[params->get_idx];
|
||||
put = put32_labels[params->put_idx];
|
||||
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);
|
||||
while (frames-- > 0) {
|
||||
goto *get;
|
||||
#define CONV24_END after
|
||||
#include "plugin_ops.h"
|
||||
#undef CONV24_END
|
||||
after:
|
||||
src += src_step;
|
||||
dst += dst_step;
|
||||
}
|
||||
}
|
||||
|
||||
static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
|
||||
snd_pcm_uframes_t dst_offset,
|
||||
const snd_pcm_channel_area_t *src_areas,
|
||||
|
|
@ -239,6 +287,11 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
|
|||
frames, ttable, params);
|
||||
return;
|
||||
} else if (nsrcs == 1 && src_tt[0].as_int == SND_PCM_PLUGIN_ROUTE_RESOLUTION) {
|
||||
if (params->use_getput)
|
||||
snd_pcm_route_convert1_one_getput(dst_area, dst_offset,
|
||||
src_areas, src_offset,
|
||||
frames, ttable, params);
|
||||
else
|
||||
snd_pcm_route_convert1_one(dst_area, dst_offset,
|
||||
src_areas, src_offset,
|
||||
frames, ttable, params);
|
||||
|
|
@ -561,8 +614,10 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
|||
src_format = slave->format;
|
||||
dst_format = snd_pcm_hw_params_get_format(params);
|
||||
}
|
||||
route->params.use_getput = snd_pcm_format_physical_width(src_format) == 24 ||
|
||||
snd_pcm_format_physical_width(dst_format) == 24;
|
||||
route->params.get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S16);
|
||||
route->params.put_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S32, dst_format);
|
||||
route->params.put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, dst_format);
|
||||
route->params.conv_idx = snd_pcm_linear_convert_index(src_format, dst_format);
|
||||
route->params.src_size = snd_pcm_format_width(src_format) / 8;
|
||||
route->params.dst_sfmt = dst_format;
|
||||
|
|
@ -730,9 +785,12 @@ static int route_load_ttable(snd_pcm_route_params_t *params, snd_pcm_stream_t st
|
|||
dptr->nsrcs = nsrcs;
|
||||
if (nsrcs == 0)
|
||||
dptr->func = snd_pcm_route_convert1_zero;
|
||||
else if (nsrcs == 1 && !att)
|
||||
dptr->func = snd_pcm_route_convert1_one;
|
||||
else if (nsrcs == 1 && !att) {
|
||||
if (params->use_getput)
|
||||
dptr->func = snd_pcm_route_convert1_one_getput;
|
||||
else
|
||||
dptr->func = snd_pcm_route_convert1_one;
|
||||
} else
|
||||
dptr->func = snd_pcm_route_convert1_many;
|
||||
if (nsrcs > 0) {
|
||||
dptr->srcs = calloc((unsigned int) nsrcs, sizeof(*srcs));
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@
|
|||
|
||||
#define as_u8c(ptr) (*(const u_int8_t*)(ptr))
|
||||
#define as_u16c(ptr) (*(const u_int16_t*)(ptr))
|
||||
#ifdef SND_LITTLE_ENDIAN
|
||||
#define as_u24c(ptr) (u_int32_t)(as_u8(ptr) | as_u8(((char *)ptr) + 1) << 8 | as_u8(((char *)ptr + 2) << 16)
|
||||
#elif defined(SND_BIG_ENDIAN)
|
||||
#define as_u24c(ptr) (u_int32_t)(as_u8(ptr) << 16 | as_u8(((char *)ptr) + 1) << 8 | as_u8(((char *)ptr + 2))
|
||||
#else
|
||||
#error "Wrong endian..."
|
||||
#endif
|
||||
#define as_u32c(ptr) (*(const u_int32_t*)(ptr))
|
||||
#define as_u64c(ptr) (*(const u_int64_t*)(ptr))
|
||||
#define as_s8c(ptr) (*(const int8_t*)(ptr))
|
||||
|
|
@ -41,10 +48,45 @@
|
|||
#define as_floatc(ptr) (*(const float_t*)(ptr))
|
||||
#define as_doublec(ptr) (*(const double_t*)(ptr))
|
||||
|
||||
#ifdef __i386__
|
||||
#define _get_triple_le(ptr) (*(u_int32_t*)(ptr) & 0xffffff)
|
||||
#define _get_triple_be(ptr) (bswap_32(*(u_int32_t*)(ptr)) & 0xffffff)
|
||||
#else
|
||||
#define _get_triple_le(ptr) (*(u_int8_t*)(ptr) | (u_int32_t)*((u_int8_t*)(ptr) + 1) << 8 | (u_int32_t)*((u_int8_t*)(ptr) + 2) << 16)
|
||||
#define _get_triple_be(ptr) ((u_int32_t)*(u_int8_t*)(ptr) << 16 | (u_int32_t)*((u_int8_t*)(ptr) + 1) << 8 | *((u_int8_t*)(ptr) + 2))
|
||||
#endif
|
||||
#define _put_triple_le(ptr,val) do { \
|
||||
u_int8_t *_tmp = (u_int8_t *)(ptr); \
|
||||
u_int32_t _val = (val); \
|
||||
_tmp[0] = _val; \
|
||||
_tmp[1] = _val >> 8; \
|
||||
_tmp[2] = _val >> 16; \
|
||||
} while(0)
|
||||
#define _put_triple_be(ptr,val) do { \
|
||||
u_int8_t *_tmp = (u_int8_t *)(ptr); \
|
||||
u_int32_t _val = (val); \
|
||||
_tmp[0] = _val >> 16; \
|
||||
_tmp[1] = _val >> 8; \
|
||||
_tmp[2] = _val; \
|
||||
} while(0)
|
||||
|
||||
#ifdef SNDRV_LITTLE_ENDIAN
|
||||
#define _get_triple(ptr) _get_triple_le(ptr)
|
||||
#define _get_triple_s(ptr) _get_triple_be(ptr)
|
||||
#define _put_triple(ptr,val) _put_triple_le(ptr,val)
|
||||
#define _put_triple_s(ptr,val) _put_triple_be(ptr,val)
|
||||
#else
|
||||
#define _get_triple(ptr) _get_triple_be(ptr)
|
||||
#define _get_triple_s(ptr) _get_triple_le(ptr)
|
||||
#define _put_triple(ptr,val) _put_triple_be(ptr,val)
|
||||
#define _put_triple_s(ptr,val) _put_triple_le(ptr,val)
|
||||
#endif
|
||||
|
||||
#ifdef COPY_LABELS
|
||||
static void *copy_labels[4] = {
|
||||
static void *copy_labels[5] = {
|
||||
&©_8,
|
||||
&©_16,
|
||||
&©_24
|
||||
&©_32,
|
||||
&©_64
|
||||
};
|
||||
|
|
@ -54,6 +96,7 @@ static void *copy_labels[4] = {
|
|||
while(0) {
|
||||
copy_8: as_s8(dst) = as_s8c(src); goto COPY_END;
|
||||
copy_16: as_s16(dst) = as_s16c(src); goto COPY_END;
|
||||
copy_24: memcpy(dst,src,3); goto COPY_END;
|
||||
copy_32: as_s32(dst) = as_s32c(src); goto COPY_END;
|
||||
copy_64: as_s64(dst) = as_s64c(src); goto COPY_END;
|
||||
}
|
||||
|
|
@ -294,7 +337,7 @@ conv_1234_123C: as_u32(dst) = as_u32c(src) ^ 0x80; goto CONV_END;
|
|||
|
||||
#ifdef GET16_LABELS
|
||||
/* src_wid src_endswap sign_toggle */
|
||||
static void *get16_labels[4 * 2 * 2] = {
|
||||
static void *get16_labels[4 * 2 * 2 + 4 * 3] = {
|
||||
&&get16_1_10, /* 8h -> 16h */
|
||||
&&get16_1_90, /* 8h ^> 16h */
|
||||
&&get16_1_10, /* 8s -> 16h */
|
||||
|
|
@ -311,6 +354,19 @@ static void *get16_labels[4 * 2 * 2] = {
|
|||
&&get16_1234_92, /* 32h ^> 16h */
|
||||
&&get16_1234_43, /* 32s -> 16h */
|
||||
&&get16_1234_C3, /* 32s ^> 16h */
|
||||
/* 3bytes format */
|
||||
&&get16_123_12, /* 24h -> 16h */
|
||||
&&get16_123_92, /* 24h ^> 16h */
|
||||
&&get16_123_32, /* 24s -> 16h */
|
||||
&&get16_123_B2, /* 24s ^> 16h */
|
||||
&&get16_123_12_20, /* 20h -> 16h */
|
||||
&&get16_123_92_20, /* 20h ^> 16h */
|
||||
&&get16_123_32_20, /* 20s -> 16h */
|
||||
&&get16_123_B2_20, /* 20s ^> 16h */
|
||||
&&get16_123_12_18, /* 18h -> 16h */
|
||||
&&get16_123_92_18, /* 18h ^> 16h */
|
||||
&&get16_123_32_18, /* 18s -> 16h */
|
||||
&&get16_123_B2_18, /* 18s ^> 16h */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -330,6 +386,18 @@ get16_1234_12: sample = as_u32c(src) >> 16; goto GET16_END;
|
|||
get16_1234_92: sample = (as_u32c(src) >> 16) ^ 0x8000; goto GET16_END;
|
||||
get16_1234_43: sample = bswap_16(as_u32c(src)); goto GET16_END;
|
||||
get16_1234_C3: sample = bswap_16(as_u32c(src) ^ 0x80); goto GET16_END;
|
||||
get16_123_12: sample = _get_triple(src) >> 8; goto GET16_END;
|
||||
get16_123_92: sample = (_get_triple(src) >> 8) ^ 0x8000; goto GET16_END;
|
||||
get16_123_32: sample = _get_triple_s(src) >> 8; goto GET16_END;
|
||||
get16_123_B2: sample = (_get_triple_s(src) >> 8) ^ 0x8000; goto GET16_END;
|
||||
get16_123_12_20: sample = _get_triple(src) >> 4; goto GET16_END;
|
||||
get16_123_92_20: sample = (_get_triple(src) >> 4) ^ 0x8000; goto GET16_END;
|
||||
get16_123_32_20: sample = _get_triple_s(src) >> 4; goto GET16_END;
|
||||
get16_123_B2_20: sample = (_get_triple_s(src) >> 4) ^ 0x8000; goto GET16_END;
|
||||
get16_123_12_18: sample = _get_triple(src) >> 2; goto GET16_END;
|
||||
get16_123_92_18: sample = (_get_triple(src) >> 2) ^ 0x8000; goto GET16_END;
|
||||
get16_123_32_18: sample = _get_triple_s(src) >> 2; goto GET16_END;
|
||||
get16_123_B2_18: sample = (_get_triple_s(src) >> 2) ^ 0x8000; goto GET16_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -374,9 +442,14 @@ put16_12_0029: as_u32(dst) = (u_int32_t)bswap_16(sample) ^ 0x80; goto PUT16_END;
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONV24_LABELS
|
||||
#define GET32_LABELS
|
||||
#define PUT32_LABELS
|
||||
#endif
|
||||
|
||||
#ifdef GET32_LABELS
|
||||
/* src_wid src_endswap sign_toggle */
|
||||
static void *get32_labels[4 * 2 * 2] = {
|
||||
static void *get32_labels[4 * 2 * 2 + 4 * 3] = {
|
||||
&&get32_1_1000, /* 8h -> 32h */
|
||||
&&get32_1_9000, /* 8h ^> 32h */
|
||||
&&get32_1_1000, /* 8s -> 32h */
|
||||
|
|
@ -393,9 +466,26 @@ static void *get32_labels[4 * 2 * 2] = {
|
|||
&&get32_1234_9234, /* 32h ^> 32h */
|
||||
&&get32_1234_4321, /* 32s -> 32h */
|
||||
&&get32_1234_C321, /* 32s ^> 32h */
|
||||
/* 3bytes format */
|
||||
&&get32_123_1230, /* 24h -> 32h */
|
||||
&&get32_123_9230, /* 24h ^> 32h */
|
||||
&&get32_123_3210, /* 24s -> 32h */
|
||||
&&get32_123_B210, /* 24s ^> 32h */
|
||||
&&get32_123_1230_20, /* 20h -> 32h */
|
||||
&&get32_123_9230_20, /* 20h ^> 32h */
|
||||
&&get32_123_3210_20, /* 20s -> 32h */
|
||||
&&get32_123_B210_20, /* 20s ^> 32h */
|
||||
&&get32_123_1230_18, /* 18h -> 32h */
|
||||
&&get32_123_9230_18, /* 18h ^> 32h */
|
||||
&&get32_123_3210_18, /* 18s -> 32h */
|
||||
&&get32_123_B210_18, /* 18s ^> 32h */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONV24_END
|
||||
#define GET32_END __conv24_get
|
||||
#endif
|
||||
|
||||
#ifdef GET32_END
|
||||
while (0) {
|
||||
get32_1_1000: sample = (u_int32_t)as_u8c(src) << 24; goto GET32_END;
|
||||
|
|
@ -412,12 +502,29 @@ get32_1234_1234: sample = as_u32c(src); goto GET32_END;
|
|||
get32_1234_9234: sample = as_u32c(src) ^ 0x80000000; goto GET32_END;
|
||||
get32_1234_4321: sample = bswap_32(as_u32c(src)); goto GET32_END;
|
||||
get32_1234_C321: sample = bswap_32(as_u32c(src) ^ 0x80); goto GET32_END;
|
||||
get32_123_1230: sample = _get_triple(src) << 8; goto GET32_END;
|
||||
get32_123_9230: sample = (_get_triple(src) << 8) ^ 0x80000000; goto GET32_END;
|
||||
get32_123_3210: sample = _get_triple_s(src) << 8; goto GET32_END;
|
||||
get32_123_B210: sample = (_get_triple_s(src) << 8) ^ 0x80000000; goto GET32_END;
|
||||
get32_123_1230_20: sample = _get_triple(src) << 12; goto GET32_END;
|
||||
get32_123_9230_20: sample = (_get_triple(src) << 12) ^ 0x80000000; goto GET32_END;
|
||||
get32_123_3210_20: sample = _get_triple_s(src) << 12; goto GET32_END;
|
||||
get32_123_B210_20: sample = (_get_triple_s(src) << 12) ^ 0x80000000; goto GET32_END;
|
||||
get32_123_1230_18: sample = _get_triple(src) << 14; goto GET32_END;
|
||||
get32_123_9230_18: sample = (_get_triple(src) << 14) ^ 0x80000000; goto GET32_END;
|
||||
get32_123_3210_18: sample = _get_triple_s(src) << 14; goto GET32_END;
|
||||
get32_123_B210_18: sample = (_get_triple_s(src) << 14) ^ 0x80000000; goto GET32_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONV24_END
|
||||
__conv24_get: goto *put;
|
||||
#define PUT32_END CONV24_END
|
||||
#endif
|
||||
|
||||
#ifdef PUT32_LABELS
|
||||
/* dst_wid dst_endswap sign_toggle */
|
||||
static void *put32_labels[4 * 2 * 2] = {
|
||||
static void *put32_labels[4 * 2 * 2 + 4 * 3] = {
|
||||
&&put32_1234_1, /* 32h -> 8h */
|
||||
&&put32_1234_9, /* 32h ^> 8h */
|
||||
&&put32_1234_1, /* 32h -> 8s */
|
||||
|
|
@ -434,9 +541,27 @@ static void *put32_labels[4 * 2 * 2] = {
|
|||
&&put32_1234_9234, /* 32h ^> 32h */
|
||||
&&put32_1234_4321, /* 32h -> 32s */
|
||||
&&put32_1234_4329, /* 32h ^> 32s */
|
||||
/* 3bytes format */
|
||||
&&put32_1234_123, /* 32h -> 24h */
|
||||
&&put32_1234_923, /* 32h ^> 24h */
|
||||
&&put32_1234_321, /* 32h -> 24s */
|
||||
&&put32_1234_329, /* 32h ^> 24s */
|
||||
&&put32_1234_123_20, /* 32h -> 24h */
|
||||
&&put32_1234_923_20, /* 32h ^> 24h */
|
||||
&&put32_1234_321_20, /* 32h -> 24s */
|
||||
&&put32_1234_329_20, /* 32h ^> 24s */
|
||||
&&put32_1234_123_18, /* 32h -> 24h */
|
||||
&&put32_1234_923_18, /* 32h ^> 24h */
|
||||
&&put32_1234_321_18, /* 32h -> 24s */
|
||||
&&put32_1234_329_18, /* 32h ^> 24s */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONV24_LABELS
|
||||
#undef GET32_LABELS
|
||||
#undef PUT32_LABELS
|
||||
#endif
|
||||
|
||||
#ifdef PUT32_END
|
||||
while (0) {
|
||||
put32_1234_1: as_u8(dst) = sample >> 24; goto PUT32_END;
|
||||
|
|
@ -453,9 +578,26 @@ put32_1234_1234: as_u32(dst) = sample; goto PUT32_END;
|
|||
put32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT32_END;
|
||||
put32_1234_4321: as_u32(dst) = bswap_32(sample); goto PUT32_END;
|
||||
put32_1234_4329: as_u32(dst) = bswap_32(sample) ^ 0x80; goto PUT32_END;
|
||||
put32_1234_123: _put_triple(dst, sample >> 8); goto PUT32_END;
|
||||
put32_1234_923: _put_triple(dst, (sample ^ 0x80000000) >> 8); goto PUT32_END;
|
||||
put32_1234_321: _put_triple_s(dst, sample >> 8); goto PUT32_END;
|
||||
put32_1234_329: _put_triple_s(dst, (sample ^ 0x80000000) >> 8); goto PUT32_END;
|
||||
put32_1234_123_20: _put_triple(dst, sample >> 12); goto PUT32_END;
|
||||
put32_1234_923_20: _put_triple(dst, (sample ^ 0x80000000) >> 12); goto PUT32_END;
|
||||
put32_1234_321_20: _put_triple_s(dst, sample >> 12); goto PUT32_END;
|
||||
put32_1234_329_20: _put_triple_s(dst, (sample ^ 0x80000000) >> 12); goto PUT32_END;
|
||||
put32_1234_123_18: _put_triple(dst, sample >> 14); goto PUT32_END;
|
||||
put32_1234_923_18: _put_triple(dst, (sample ^ 0x80000000) >> 14); goto PUT32_END;
|
||||
put32_1234_321_18: _put_triple_s(dst, sample >> 14); goto PUT32_END;
|
||||
put32_1234_329_18: _put_triple_s(dst, (sample ^ 0x80000000) >> 14); goto PUT32_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONV24_END
|
||||
#undef GET32_END
|
||||
#undef PUT32_END
|
||||
#endif
|
||||
|
||||
#ifdef GETU_LABELS
|
||||
/* width endswap sign_toggle */
|
||||
static void *getu_labels[4 * 2 * 2] = {
|
||||
|
|
@ -924,3 +1066,13 @@ norms_32_s32s: _norms(src, dst, 32, 1, 32, 1); goto NORMS_END;
|
|||
#undef as_s32c
|
||||
#undef as_floatc
|
||||
#undef as_doublec
|
||||
|
||||
#undef _get_triple
|
||||
#undef _get_triple_s
|
||||
#undef _get_triple_le
|
||||
#undef _get_triple_be
|
||||
#undef _put_triple
|
||||
#undef _put_triple_s
|
||||
#undef _put_triple_le
|
||||
#undef _put_triple_be
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue