Finished lfloat plugin.

Added code to plug plugin to handle linear float / integer conversions.
This commit is contained in:
Jaroslav Kysela 2001-11-27 14:24:44 +00:00
parent 4efc53523a
commit 095cbbb467
6 changed files with 339 additions and 119 deletions

View file

@ -194,6 +194,11 @@ snd_pcm_ladspa_write_areas(snd_pcm_t *pcm,
// 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;
}
@ -210,6 +215,11 @@ snd_pcm_ladspa_read_areas(snd_pcm_t *pcm,
// 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;
}

View file

@ -23,6 +23,9 @@
#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 = "";
@ -31,83 +34,65 @@ 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;
}
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)
{
#define CONV_LABELS
#define GET32_LABELS
#define PUT32F_LABELS
#include "plugin_ops.h"
#undef CONV_LABELS
void *conv = conv_labels[convidx];
#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);
@ -116,11 +101,62 @@ void snd_pcm_lfloat_convert(const snd_pcm_channel_area_t *dst_areas, snd_pcm_ufr
dst_step = snd_pcm_channel_area_step(dst_area);
frames1 = frames;
while (frames1-- > 0) {
goto *conv;
#define CONV_END after
goto *get32;
#define GET32_END sample_loaded
#include "plugin_ops.h"
#undef CONV_END
after:
#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_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 PUT32_LABELS
#define GET32F_LABELS
#include "plugin_ops.h"
#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 = 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 *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 PUT32_END
sample_put:
src += src_step;
dst += dst_step;
}
@ -211,6 +247,8 @@ static int snd_pcm_lfloat_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
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,
@ -218,12 +256,22 @@ static int snd_pcm_lfloat_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
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;
}
@ -239,9 +287,10 @@ snd_pcm_lfloat_write_areas(snd_pcm_t *pcm,
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;
}
@ -258,9 +307,10 @@ snd_pcm_lfloat_read_areas(snd_pcm_t *pcm,
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;
}
@ -324,7 +374,7 @@ int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
pcm->hw_ptr = &lfloat->plug.hw_ptr;
pcm->appl_ptr = &lfloat->plug.appl_ptr;
*pcmp = pcm;
return 0;
}

View file

@ -1877,7 +1877,7 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
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);
@ -1888,9 +1888,8 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
#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');

View file

@ -99,17 +99,6 @@ static snd_pcm_format_t linear_preferred_formats[] = {
SND_PCM_FORMAT_S16_LE,
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,
@ -122,7 +111,29 @@ static snd_pcm_format_t linear_preferred_formats[] = {
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[] = {
@ -131,13 +142,29 @@ 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:
@ -155,7 +182,8 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
}
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];
@ -164,9 +192,31 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
}
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) {
@ -193,12 +243,6 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
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;
@ -361,10 +405,27 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
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 &&
@ -466,12 +527,16 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
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;
}
@ -633,6 +698,21 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
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)

View file

@ -87,6 +87,7 @@ int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_f
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);

View file

@ -19,7 +19,6 @@
*
*/
#define as_u8(ptr) (*(u_int8_t*)(ptr))
#define as_u16(ptr) (*(u_int16_t*)(ptr))
#define as_u32(ptr) (*(u_int32_t*)(ptr))
@ -28,6 +27,8 @@
#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))
@ -37,6 +38,8 @@
#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] = {
@ -333,14 +336,14 @@ get16_1234_C3: sample = bswap_16(as_u32c(src) ^ 0x80); goto GET16_END;
#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 */
@ -374,9 +377,9 @@ put16_12_0029: as_u32(dst) = (u_int32_t)bswap_16(sample) ^ 0x80; goto PUT16_END;
#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 */
@ -415,10 +418,10 @@ get32_1234_C321: sample = bswap_32(as_u32c(src) ^ 0x80); goto GET32_END;
#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 */
@ -574,6 +577,72 @@ put_1234_4321: as_s32(dst) = bswap_32(sample); goto PUT_END;
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,
@ -844,3 +913,14 @@ norms_32_s32s: _norms(src, dst, 32, 1, 32, 1); goto NORMS_END;
#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