Added code to plug plugin to handle linear float / integer conversions.
// snd_pcm_ladspa_t *ladspa = pcm->private_data;
if (size > *slave_sizep)
size = *slave_sizep;
+#if 1 // no processing - for testing purposes only
+ snd_pcm_areas_copy(slave_areas, slave_offset,
+ areas, offset,
+ pcm->channels, size, pcm->format);
+#endif
*slave_sizep = size;
return size;
}
// snd_pcm_ladspa_t *ladspa = pcm->private_data;
if (size > *slave_sizep)
size = *slave_sizep;
+#if 1 // no processing - for testing purposes only
+ snd_pcm_areas_copy(areas, offset,
+ slave_areas, slave_offset,
+ pcm->channels, size, pcm->format);
+#endif
*slave_sizep = size;
return size;
}
#include "pcm_local.h"
#include "pcm_plugin.h"
+typedef float float_t;
+typedef double double_t;
+
#ifndef PIC
/* entry for static linking */
const char *_snd_module_pcm_float = "";
typedef struct {
/* This field need to be the first */
snd_pcm_plugin_t plug;
- unsigned int conv_idx;
+ unsigned int int32_idx;
+ unsigned int float32_idx;
snd_pcm_format_t sformat;
+ void (*func)(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 get32idx, unsigned int put32floatidx);
} snd_pcm_lfloat_t;
-int snd_pcm_lfloat_convert_index(snd_pcm_format_t src_format,
- snd_pcm_format_t dst_format)
+int snd_pcm_lfloat_get_s32_index(snd_pcm_format_t format)
{
- int src_endian, dst_endian, sign, src_width, dst_width;
+ int width, endian;
- sign = (snd_pcm_format_signed(src_format) !=
- snd_pcm_format_signed(dst_format));
+ switch (format) {
+ case SND_PCM_FORMAT_FLOAT_LE:
+ case SND_PCM_FORMAT_FLOAT_BE:
+ width = 32;
+ break;
+ case SND_PCM_FORMAT_FLOAT64_LE:
+ case SND_PCM_FORMAT_FLOAT64_BE:
+ width = 64;
+ break;
+ default:
+ return -EINVAL;
+ }
#ifdef SND_LITTLE_ENDIAN
- src_endian = snd_pcm_format_big_endian(src_format);
- dst_endian = snd_pcm_format_big_endian(dst_format);
+ endian = snd_pcm_format_big_endian(format);
#else
- src_endian = snd_pcm_format_little_endian(src_format);
- dst_endian = snd_pcm_format_little_endian(dst_format);
+ endian = snd_pcm_format_little_endian(format);
#endif
-
- if (src_endian < 0)
- src_endian = 0;
- if (dst_endian < 0)
- dst_endian = 0;
-
- src_width = snd_pcm_format_width(src_format) / 8 - 1;
- dst_width = snd_pcm_format_width(dst_format) / 8 - 1;
-
- return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian;
+ return ((width / 32)-1) * 2 + endian;
}
-int snd_pcm_lfloat_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
+int snd_pcm_lfloat_put_s32_index(snd_pcm_format_t format)
{
- int sign, width, 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
- endian = snd_pcm_format_little_endian(src_format);
-#endif
- if (endian < 0)
- endian = 0;
- return width * 4 + endian * 2 + sign;
+ return snd_pcm_lfloat_get_s32_index(format);
}
-int snd_pcm_lfloat_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
+void snd_pcm_lfloat_convert_integer_float(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 get32idx, unsigned int put32floatidx)
{
- int sign, width, endian;
- sign = (snd_pcm_format_signed(src_format) !=
- snd_pcm_format_signed(dst_format));
- width = snd_pcm_format_width(dst_format) / 8 - 1;
-#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;
- return width * 4 + endian * 2 + sign;
+#define GET32_LABELS
+#define PUT32F_LABELS
+#include "plugin_ops.h"
+#undef PUT32F_LABELS
+#undef GET32_LABELS
+ void *get32 = get32_labels[get32idx];
+ void *put32float = put32float_labels[put32floatidx];
+ unsigned int channel;
+ for (channel = 0; channel < channels; ++channel) {
+ const char *src;
+ char *dst;
+ int src_step, dst_step;
+ snd_pcm_uframes_t frames1;
+ int32_t sample = 0;
+ float tmp_float;
+ double tmp_double;
+ 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 *get32;
+#define GET32_END sample_loaded
+#include "plugin_ops.h"
+#undef GET32_END
+ sample_loaded:
+ goto *put32float;
+#define PUT32F_END sample_put
+#include "plugin_ops.h"
+#undef PUT32F_END
+ sample_put:
+ src += src_step;
+ dst += dst_step;
+ }
+ }
}
-void snd_pcm_lfloat_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_lfloat_convert_float_integer(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 put32idx, unsigned int get32floatidx)
{
-#define CONV_LABELS
+#define PUT32_LABELS
+#define GET32F_LABELS
#include "plugin_ops.h"
-#undef CONV_LABELS
- void *conv = conv_labels[convidx];
+#undef GET32F_LABELS
+#undef PUT32_LABELS
+ void *put32 = put32_labels[put32idx];
+ void *get32float = get32float_labels[get32floatidx];
unsigned int channel;
for (channel = 0; channel < channels; ++channel) {
const char *src;
char *dst;
int src_step, dst_step;
snd_pcm_uframes_t frames1;
+ int32_t sample;
+ int64_t sample64;
+ float tmp_float;
+ double tmp_double;
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_step = snd_pcm_channel_area_step(dst_area);
frames1 = frames;
while (frames1-- > 0) {
- goto *conv;
-#define CONV_END after
+ goto *get32float;
+#define GET32F_END sample_loaded
+#include "plugin_ops.h"
+#undef GET32F_END
+ sample_loaded:
+ goto *put32;
+#define PUT32_END sample_put
#include "plugin_ops.h"
-#undef CONV_END
- after:
+#undef PUT32_END
+ sample_put:
src += src_step;
dst += dst_step;
}
static int snd_pcm_lfloat_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_lfloat_t *lfloat = pcm->private_data;
+ snd_pcm_t *slave = lfloat->plug.slave;
+ snd_pcm_format_t src_format, dst_format;
int err = snd_pcm_hw_params_slave(pcm, params,
snd_pcm_lfloat_hw_refine_cchange,
snd_pcm_lfloat_hw_refine_sprepare,
snd_pcm_plugin_hw_params_slave);
if (err < 0)
return err;
- if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
- lfloat->conv_idx = snd_pcm_lfloat_convert_index(snd_pcm_hw_params_get_format(params),
- lfloat->sformat);
- else
- lfloat->conv_idx = snd_pcm_lfloat_convert_index(lfloat->sformat,
- snd_pcm_hw_params_get_format(params));
+ if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
+ src_format = snd_pcm_hw_params_get_format(params);
+ dst_format = slave->format;
+ } else {
+ src_format = slave->format;
+ 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->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->float32_idx = snd_pcm_lfloat_get_s32_index(src_format);
+ lfloat->func = snd_pcm_lfloat_convert_float_integer;
+ }
return 0;
}
snd_pcm_lfloat_t *lfloat = pcm->private_data;
if (size > *slave_sizep)
size = *slave_sizep;
- snd_pcm_lfloat_convert(slave_areas, slave_offset,
- areas, offset,
- pcm->channels, size, lfloat->conv_idx);
+ lfloat->func(slave_areas, slave_offset,
+ areas, offset,
+ pcm->channels, size,
+ lfloat->int32_idx, lfloat->float32_idx);
*slave_sizep = size;
return size;
}
snd_pcm_lfloat_t *lfloat = pcm->private_data;
if (size > *slave_sizep)
size = *slave_sizep;
- snd_pcm_lfloat_convert(areas, offset,
- slave_areas, slave_offset,
- pcm->channels, size, lfloat->conv_idx);
+ lfloat->func(areas, offset,
+ slave_areas, slave_offset,
+ pcm->channels, size,
+ lfloat->int32_idx, lfloat->float32_idx);
*slave_sizep = size;
return size;
}
pcm->hw_ptr = &lfloat->plug.hw_ptr;
pcm->appl_ptr = &lfloat->plug.appl_ptr;
*pcmp = pcm;
-
+
return 0;
}
if (!doit)
continue;
#ifdef RULES_DEBUG
- snd_output_printf(log, "Rule %d: ", k);
+ snd_output_printf(log, "Rule %d (%p): ", k, r->func);
if (r->var >= 0) {
snd_output_printf(log, "%s=", snd_pcm_hw_param_name(r->var));
snd_pcm_hw_param_dump(params, r->var, log);
#ifdef RULES_DEBUG
if (r->var >= 0)
snd_pcm_hw_param_dump(params, r->var, log);
- snd_output_putc(log, ' ');
for (d = 0; r->deps[d] >= 0; d++) {
- snd_output_printf(log, "%s=", snd_pcm_hw_param_name(r->deps[d]));
+ snd_output_printf(log, " %s=", snd_pcm_hw_param_name(r->deps[d]));
snd_pcm_hw_param_dump(params, r->deps[d], log);
}
snd_output_putc(log, '\n');
SND_PCM_FORMAT_U16_LE,
#endif
#ifdef SND_LITTLE_ENDIAN
- SND_PCM_FORMAT_S24_LE,
- SND_PCM_FORMAT_U24_LE,
- SND_PCM_FORMAT_S24_BE,
- SND_PCM_FORMAT_U24_BE,
-#else
- SND_PCM_FORMAT_S24_BE,
- SND_PCM_FORMAT_U24_BE,
- SND_PCM_FORMAT_S24_LE,
- SND_PCM_FORMAT_U24_LE,
-#endif
-#ifdef SND_LITTLE_ENDIAN
SND_PCM_FORMAT_S32_LE,
SND_PCM_FORMAT_U32_LE,
SND_PCM_FORMAT_S32_BE,
SND_PCM_FORMAT_U32_LE,
#endif
SND_PCM_FORMAT_S8,
- SND_PCM_FORMAT_U8
+ SND_PCM_FORMAT_U8,
+#ifdef SND_LITTLE_ENDIAN
+ SND_PCM_FORMAT_FLOAT_LE,
+ SND_PCM_FORMAT_FLOAT64_LE,
+ SND_PCM_FORMAT_FLOAT_BE,
+ SND_PCM_FORMAT_FLOAT64_BE,
+#else
+ SND_PCM_FORMAT_FLOAT_BE,
+ SND_PCM_FORMAT_FLOAT64_BE,
+ SND_PCM_FORMAT_FLOAT_LE,
+ SND_PCM_FORMAT_FLOAT64_LE,
+#endif
+#ifdef SND_LITTLE_ENDIAN
+ SND_PCM_FORMAT_S24_LE,
+ SND_PCM_FORMAT_U24_LE,
+ SND_PCM_FORMAT_S24_BE,
+ SND_PCM_FORMAT_U24_BE,
+#else
+ SND_PCM_FORMAT_S24_BE,
+ SND_PCM_FORMAT_U24_BE,
+ SND_PCM_FORMAT_S24_LE,
+ SND_PCM_FORMAT_U24_LE,
+#endif
};
static snd_pcm_format_t nonlinear_preferred_formats[] = {
SND_PCM_FORMAT_IMA_ADPCM,
};
+static snd_pcm_format_t float_preferred_formats[] = {
+#ifdef SND_LITTLE_ENDIAN
+ SND_PCM_FORMAT_FLOAT_LE,
+ SND_PCM_FORMAT_FLOAT64_LE,
+ SND_PCM_FORMAT_FLOAT_BE,
+ SND_PCM_FORMAT_FLOAT64_BE,
+#else
+ SND_PCM_FORMAT_FLOAT_BE,
+ SND_PCM_FORMAT_FLOAT64_BE,
+ SND_PCM_FORMAT_FLOAT_LE,
+ SND_PCM_FORMAT_FLOAT64_LE,
+#endif
+};
+
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;
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))
return format;
- if (!snd_pcm_format_mask_test(&lin, format)) {
+ if (!snd_pcm_format_mask_test(&lin, format) &&
+ !snd_pcm_format_mask_test(&fl, format)) {
unsigned int i;
switch (format) {
case SND_PCM_FORMAT_MU_LAW:
}
snd_mask_intersect(&lin, format_mask);
- if (snd_mask_empty(&lin)) {
+ snd_mask_intersect(&fl, format_mask);
+ if (snd_mask_empty(&lin) && snd_mask_empty(&fl)) {
unsigned int i;
for (i = 0; i < sizeof(nonlinear_preferred_formats) / sizeof(nonlinear_preferred_formats[0]); ++i) {
snd_pcm_format_t f = nonlinear_preferred_formats[i];
}
return SND_PCM_FORMAT_UNKNOWN;
}
- w = snd_pcm_format_width(format);
- u = snd_pcm_format_unsigned(format);
- e = snd_pcm_format_big_endian(format);
+ if (snd_pcm_format_float(format)) {
+ if (snd_pcm_format_mask_test(&fl, format)) {
+ unsigned int i;
+ for (i = 0; i < sizeof(float_preferred_formats) / sizeof(float_preferred_formats[0]); ++i) {
+ snd_pcm_format_t f = float_preferred_formats[i];
+ if (snd_pcm_format_mask_test(format_mask, f))
+ return f;
+ }
+ }
+ w = 32;
+ u = 0;
+ e = snd_pcm_format_big_endian(format);
+ } else if (snd_mask_empty(&lin)) {
+ unsigned int i;
+ for (i = 0; i < sizeof(float_preferred_formats) / sizeof(float_preferred_formats[0]); ++i) {
+ snd_pcm_format_t f = float_preferred_formats[i];
+ if (snd_pcm_format_mask_test(format_mask, f))
+ return f;
+ }
+ return SND_PCM_FORMAT_UNKNOWN;
+ } else {
+ w = snd_pcm_format_width(format);
+ u = snd_pcm_format_unsigned(format);
+ e = snd_pcm_format_big_endian(format);
+ }
w1 = w;
dw = 8;
for (wid = 0; wid < 4; ++wid) {
return SND_PCM_FORMAT_UNKNOWN;
}
-#define SND_PCM_FMTBIT_PLUG (SND_PCM_FMTBIT_LINEAR | \
- (1 << SND_PCM_FORMAT_MU_LAW) | \
- (1 << SND_PCM_FORMAT_A_LAW) | \
- (1 << SND_PCM_FORMAT_IMA_ADPCM))
-
-
static void snd_pcm_plug_clear(snd_pcm_t *pcm)
{
snd_pcm_plug_t *plug = pcm->private_data;
f = snd_pcm_adpcm_open;
break;
default:
- assert(snd_pcm_format_linear(clt->format));
- f = snd_pcm_linear_open;
+ if (snd_pcm_format_float(clt->format)) {
+ f = snd_pcm_lfloat_open;
+ } else {
+ assert(snd_pcm_format_linear(clt->format));
+ f = snd_pcm_linear_open;
+ }
break;
}
+ } else if (snd_pcm_format_float(slv->format)) {
+ /* Conversion is done in another plugin */
+ if (clt->format == slv->format &&
+ clt->rate == slv->rate &&
+ clt->channels == slv->channels)
+ return 0;
+ cfmt = clt->format;
+ if (snd_pcm_format_linear(clt->format))
+ f = snd_pcm_lfloat_open;
+ else {
+ assert(0); /* TODO */
+ return -EINVAL;
+ }
} else {
/* No conversion is needed */
if (clt->format == slv->format &&
static int snd_pcm_plug_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
{
- unsigned int rate_min;
+ unsigned int rate_min, channels_max;
/* HACK: to avoid overflow in PARTBIT_RATE code */
rate_min = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, NULL);
if (rate_min < 4000)
- _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, 4000, 1);
+ _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, 4000, 0);
+ /* HACK: to avoid overflow in PERIOD_SIZE code */
+ channels_max = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, NULL);
+ if (channels_max > 10000)
+ _snd_pcm_hw_param_set_max(params, SND_PCM_HW_PARAM_CHANNELS, 10000, 0);
return 0;
}
snd_pcm_format_mask_set(&fmt_mask, format);
}
+ if (snd_pcm_format_mask_empty(&fmt_mask)) {
+ SNDERR("Unable to find an useable client format");
+ for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
+ if (!snd_pcm_format_mask_test(format_mask, format))
+ continue;
+ SNDERR("Format: %s", snd_pcm_format_name(format));
+ }
+ for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
+ if (!snd_pcm_format_mask_test(sformat_mask, format))
+ continue;
+ SNDERR("Slave format: %s", snd_pcm_format_name(format));
+ }
+ return -EINVAL;
+ }
+
err = _snd_pcm_hw_param_set_mask(params,
SND_PCM_HW_PARAM_FORMAT, &fmt_mask);
if (err < 0)
int snd_pcm_linear_convert_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int close_slave);
int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
+int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
*
*/
-
#define as_u8(ptr) (*(u_int8_t*)(ptr))
#define as_u16(ptr) (*(u_int16_t*)(ptr))
#define as_u32(ptr) (*(u_int32_t*)(ptr))
#define as_s16(ptr) (*(int16_t*)(ptr))
#define as_s32(ptr) (*(int32_t*)(ptr))
#define as_s64(ptr) (*(int64_t*)(ptr))
+#define as_float(ptr) (*(float_t*)(ptr))
+#define as_double(ptr) (*(double_t*)(ptr))
#define as_u8c(ptr) (*(const u_int8_t*)(ptr))
#define as_u16c(ptr) (*(const u_int16_t*)(ptr))
#define as_s16c(ptr) (*(const int16_t*)(ptr))
#define as_s32c(ptr) (*(const int32_t*)(ptr))
#define as_s64c(ptr) (*(const int64_t*)(ptr))
+#define as_floatc(ptr) (*(const float_t*)(ptr))
+#define as_doublec(ptr) (*(const double_t*)(ptr))
#ifdef COPY_LABELS
static void *copy_labels[4] = {
#ifdef PUT16_LABELS
/* dst_wid dst_endswap sign_toggle */
static void *put16_labels[4 * 2 * 2 * 4 * 2] = {
- &&put16_12_1, /* 16h -> 8h */
- &&put16_12_9, /* 16h ^> 8h */
- &&put16_12_1, /* 16h -> 8s */
- &&put16_12_9, /* 16h ^> 8s */
- &&put16_12_12, /* 16h -> 16h */
- &&put16_12_92, /* 16h ^> 16h */
- &&put16_12_21, /* 16h -> 16s */
- &&put16_12_29, /* 16h ^> 16s */
+ &&put16_12_1, /* 16h -> 8h */
+ &&put16_12_9, /* 16h ^> 8h */
+ &&put16_12_1, /* 16h -> 8s */
+ &&put16_12_9, /* 16h ^> 8s */
+ &&put16_12_12, /* 16h -> 16h */
+ &&put16_12_92, /* 16h ^> 16h */
+ &&put16_12_21, /* 16h -> 16s */
+ &&put16_12_29, /* 16h ^> 16s */
&&put16_12_0120, /* 16h -> 24h */
&&put16_12_0920, /* 16h ^> 24h */
&&put16_12_0210, /* 16h -> 24s */
#ifdef GET32_LABELS
/* src_wid src_endswap sign_toggle */
static void *get32_labels[4 * 2 * 2] = {
- &&get32_1_1000, /* 8h -> 32h */
- &&get32_1_9000, /* 8h ^> 32h */
- &&get32_1_1000, /* 8s -> 32h */
+ &&get32_1_1000, /* 8h -> 32h */
+ &&get32_1_9000, /* 8h ^> 32h */
+ &&get32_1_1000, /* 8s -> 32h */
&&get32_1_9000, /* 8s ^> 32h */
&&get32_12_1200, /* 16h -> 32h */
&&get32_12_9200, /* 16h ^> 32h */
#ifdef PUT32_LABELS
/* dst_wid dst_endswap sign_toggle */
static void *put32_labels[4 * 2 * 2] = {
- &&put32_1234_1, /* 32h -> 8h */
- &&put32_1234_9, /* 32h ^> 8h */
- &&put32_1234_1, /* 32h -> 8s */
- &&put32_1234_9, /* 32h ^> 8s */
+ &&put32_1234_1, /* 32h -> 8h */
+ &&put32_1234_9, /* 32h ^> 8h */
+ &&put32_1234_1, /* 32h -> 8s */
+ &&put32_1234_9, /* 32h ^> 8s */
&&put32_1234_12, /* 32h -> 16h */
&&put32_1234_92, /* 32h ^> 16h */
&&put32_1234_21, /* 32h -> 16s */
put_1234_4329: as_u32(dst) = bswap_32(sample) ^ 0x80; goto PUT_END;
#endif
+#ifdef PUT32F_LABELS
+/* type (0 = float, 1 = float64), endswap */
+static void *put32float_labels[2 * 2] = {
+ &&put32f_1234_1234F, /* 32h -> (float)h */
+ &&put32f_1234_4321F, /* 32h -> (float)s */
+ &&put32f_1234_1234D, /* 32h -> (float64)h */
+ &&put32f_1234_4321D, /* 32h -> (float64)s */
+};
+#endif
+
+#ifdef PUT32F_END
+put32f_1234_1234F: as_float(dst) = (float_t)((int32_t)sample) / (float_t)0x80000000UL; goto PUT32F_END;
+put32f_1234_4321F: tmp_float = (float_t)((int32_t)sample) / (float_t)0x80000000UL;
+ as_u32(dst) = bswap_32(as_u32c(&tmp_float)); goto PUT32F_END;
+put32f_1234_1234D: as_double(dst) = (double_t)((int32_t)sample) / (double_t)0x80000000UL; goto PUT32F_END;
+put32f_1234_4321D: tmp_double = (double_t)((int32_t)sample) / (double_t)0x80000000UL;
+ as_u64(dst) = bswap_64(as_u64c(&tmp_double)); goto PUT32F_END;
+#endif
+
+#ifdef GET32F_LABELS
+/* type (0 = float, 1 = float64), endswap */
+static void *get32float_labels[2 * 2] = {
+ &&get32f_1234F_1234, /* (float)h -> 32h */
+ &&get32f_4321F_1234, /* (float)s -> 32h */
+ &&get32f_1234D_1234, /* (float64)h -> 32h */
+ &&get32f_4321D_1234, /* (float64)s -> 32h */
+};
+#endif
+
+#ifdef GET32F_END
+get32f_1234F_1234: tmp_float = as_floatc(src);
+ if (tmp_float >= 1.0)
+ sample = 0x7fffffff;
+ else if (tmp_float <= -1.0)
+ sample = 0x80000000;
+ else
+ sample = (int32_t)(tmp_float * (float_t)0x80000000UL);
+ goto GET32F_END;
+get32f_4321F_1234: sample = bswap_32(as_u32c(src));
+ tmp_float = as_floatc(&sample);
+ if (tmp_float >= 1.0)
+ sample = 0x7fffffff;
+ else if (tmp_float <= -1.0)
+ sample = 0x80000000;
+ else
+ sample = (int32_t)(tmp_float * (float_t)0x80000000UL);
+ goto GET32F_END;
+get32f_1234D_1234: tmp_double = as_doublec(src);
+ if (tmp_double >= 1.0)
+ sample = 0x7fffffff;
+ else if (tmp_double <= -1.0)
+ sample = 0x80000000;
+ else
+ sample = (int32_t)(tmp_double * (double_t)0x80000000UL);
+ goto GET32F_END;
+get32f_4321D_1234: sample64 = bswap_64(as_u64c(src));
+ tmp_double = as_doublec(&sample);
+ if (tmp_double >= 1.0)
+ sample = 0x7fffffff;
+ else if (tmp_double <= -1.0)
+ sample = 0x80000000;
+ else
+ sample = (int32_t)(tmp_double * (double_t)0x80000000UL);
+ goto GET32F_END;
+#endif
+
#ifdef NORMS_LABELS
static inline void _norms(const void *src, void *dst,
int src_wid,
#undef as_s8
#undef as_s16
#undef as_s32
+#undef as_float
+#undef as_double
+
+#undef as_u8c
+#undef as_u16c
+#undef as_u32c
+#undef as_s8c
+#undef as_s16c
+#undef as_s32c
+#undef as_floatc
+#undef as_doublec