mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-28 05:40:23 -04:00
Permit to PCM plug configuration to specify unchanged parameters. Added support for RT signals to async interface. Added ops for PCM mix.
This commit is contained in:
parent
a5b77b03f6
commit
fcd164e622
15 changed files with 492 additions and 158 deletions
|
|
@ -124,6 +124,9 @@ pcm.NAME {
|
|||
pcm STR # Slave PCM name
|
||||
# or
|
||||
pcm { } # Slave PCM definition
|
||||
[format STR] # Slave format (default nearest) or "unchanged"
|
||||
[channels INT] # Slave channels (default nearest) or "unchanged"
|
||||
[rate INT] # Slave rate (default nearest) or "unchanged"
|
||||
}
|
||||
ttable { # Transfer table (bidimensional compound of
|
||||
# cchannels * schannels numbers)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ typedef struct sndrv_seq_event snd_seq_event_t;
|
|||
#include "asoundlib.h"
|
||||
#include "list.h"
|
||||
|
||||
extern int snd_async_signo;
|
||||
|
||||
struct _snd_async_handler {
|
||||
enum {
|
||||
SND_ASYNC_HANDLER_GENERIC,
|
||||
|
|
|
|||
20
src/async.c
20
src/async.c
|
|
@ -22,6 +22,22 @@
|
|||
#include "control/control_local.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef SND_ASYNC_RT_SIGNAL
|
||||
int snd_async_signo;
|
||||
void snd_async_init(void) __attribute__ ((constructor));
|
||||
|
||||
void snd_async_init(void)
|
||||
{
|
||||
snd_async_signo = __libc_allocate_rtsig(0);
|
||||
if (snd_async_signo < 0) {
|
||||
SNDERR("Unable to find a RT signal to use for snd_async");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int snd_async_signo = SIGIO;
|
||||
#endif
|
||||
|
||||
static struct list_head snd_async_handlers;
|
||||
|
||||
static void snd_async_handler(int signo ATTRIBUTE_UNUSED, siginfo_t *siginfo, void *context ATTRIBUTE_UNUSED)
|
||||
|
|
@ -59,7 +75,7 @@ int snd_async_add_handler(snd_async_handler_t **handler, int fd,
|
|||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
act.sa_sigaction = snd_async_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
err = sigaction(SIGIO, &act, NULL);
|
||||
err = sigaction(snd_async_signo, &act, NULL);
|
||||
if (err < 0) {
|
||||
SYSERR("sigaction");
|
||||
return -errno;
|
||||
|
|
@ -76,7 +92,7 @@ int snd_async_del_handler(snd_async_handler_t *handler)
|
|||
struct sigaction act;
|
||||
act.sa_flags = 0;
|
||||
act.sa_handler = SIG_DFL;
|
||||
err = sigaction(SIGIO, &act, NULL);
|
||||
err = sigaction(snd_async_signo, &act, NULL);
|
||||
if (err < 0) {
|
||||
SYSERR("sigaction");
|
||||
return -errno;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,10 @@ int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name)
|
|||
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid)
|
||||
{
|
||||
assert(ctl);
|
||||
if (sig == 0)
|
||||
sig = SIGIO;
|
||||
if (pid == 0)
|
||||
pid = getpid();
|
||||
return ctl->ops->async(ctl, sig, pid);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -412,7 +416,7 @@ int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
|
|||
was_empty = list_empty(&ctl->async_handlers);
|
||||
list_add_tail(&h->hlist, &ctl->async_handlers);
|
||||
if (was_empty) {
|
||||
err = snd_ctl_async(ctl, getpid(), SIGIO);
|
||||
err = snd_ctl_async(ctl, getpid(), snd_async_signo);
|
||||
if (err < 0) {
|
||||
snd_async_del_handler(h);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -90,14 +90,10 @@ static int snd_ctl_hw_async(snd_ctl_t *ctl, int sig, pid_t pid)
|
|||
}
|
||||
if (sig < 0)
|
||||
return 0;
|
||||
if (sig == 0)
|
||||
sig = SIGIO;
|
||||
if (fcntl(fd, F_SETSIG, sig) < 0) {
|
||||
SYSERR("F_SETSIG failed");
|
||||
return -errno;
|
||||
}
|
||||
if (pid == 0)
|
||||
pid = getpid();
|
||||
if (fcntl(fd, F_SETOWN, pid) < 0) {
|
||||
SYSERR("F_SETOWN failed");
|
||||
return -errno;
|
||||
|
|
|
|||
|
|
@ -931,7 +931,7 @@ int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
|
|||
was_empty = list_empty(&pcm->async_handlers);
|
||||
list_add_tail(&h->hlist, &pcm->async_handlers);
|
||||
if (was_empty) {
|
||||
err = snd_pcm_async(pcm, getpid(), SIGIO);
|
||||
err = snd_pcm_async(pcm, getpid(), snd_async_signo);
|
||||
if (err < 0) {
|
||||
snd_async_del_handler(h);
|
||||
return err;
|
||||
|
|
@ -1923,7 +1923,7 @@ int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *param
|
|||
*/
|
||||
void snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
|
||||
{
|
||||
snd_pcm_access_mask_copy(mask, (snd_pcm_access_mask_t*) ¶ms->masks[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK]);
|
||||
snd_pcm_access_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2002,7 +2002,7 @@ int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *param
|
|||
*/
|
||||
void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
|
||||
{
|
||||
snd_pcm_format_mask_copy(mask, (snd_pcm_format_mask_t*) ¶ms->masks[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK]);
|
||||
snd_pcm_format_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2081,7 +2081,7 @@ int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *pa
|
|||
*/
|
||||
void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
|
||||
{
|
||||
snd_pcm_subformat_mask_copy(mask, (snd_pcm_subformat_mask_t*) ¶ms->masks[SND_PCM_HW_PARAM_SUBFORMAT - SND_PCM_HW_PARAM_FIRST_MASK]);
|
||||
snd_pcm_subformat_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4365,9 +4365,9 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
|||
const char *str;
|
||||
struct {
|
||||
unsigned int index;
|
||||
int mandatory;
|
||||
int flags;
|
||||
void *ptr;
|
||||
int valid;
|
||||
int present;
|
||||
} fields[count];
|
||||
unsigned int k;
|
||||
snd_config_t *pcm_conf = NULL;
|
||||
|
|
@ -4393,9 +4393,9 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
|||
va_start(args, count);
|
||||
for (k = 0; k < count; ++k) {
|
||||
fields[k].index = va_arg(args, int);
|
||||
fields[k].mandatory = va_arg(args, int);
|
||||
fields[k].flags = va_arg(args, int);
|
||||
fields[k].ptr = va_arg(args, void *);
|
||||
fields[k].valid = 0;
|
||||
fields[k].present = 0;
|
||||
}
|
||||
va_end(args);
|
||||
snd_config_for_each(i, next, conf) {
|
||||
|
|
@ -4427,6 +4427,11 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
|||
SNDERR("invalid type for %s", id);
|
||||
goto _err;
|
||||
}
|
||||
if ((fields[k].flags & SCONF_UNCHANGED) &&
|
||||
strcasecmp(str, "unchanged") == 0) {
|
||||
*(snd_pcm_format_t*)fields[k].ptr = (snd_pcm_format_t) -2;
|
||||
break;
|
||||
}
|
||||
f = snd_pcm_format_value(str);
|
||||
if (f == SND_PCM_FORMAT_UNKNOWN) {
|
||||
SNDERR("unknown format");
|
||||
|
|
@ -4437,13 +4442,21 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
if ((fields[k].flags & SCONF_UNCHANGED)) {
|
||||
err = snd_config_get_string(n, &str);
|
||||
if (err >= 0 &&
|
||||
strcasecmp(str, "unchanged") == 0) {
|
||||
*(int*)fields[k].ptr = -2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
err = snd_config_get_integer(n, &v);
|
||||
if (err < 0)
|
||||
goto _invalid;
|
||||
*(int*)fields[k].ptr = v;
|
||||
break;
|
||||
}
|
||||
fields[k].valid = 1;
|
||||
fields[k].present = 1;
|
||||
break;
|
||||
}
|
||||
if (k < count)
|
||||
|
|
@ -4458,7 +4471,7 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
|||
goto _err;
|
||||
}
|
||||
for (k = 0; k < count; ++k) {
|
||||
if (fields[k].mandatory && !fields[k].valid) {
|
||||
if ((fields[k].flags & SCONF_MANDATORY) && !fields[k].present) {
|
||||
SNDERR("missing field %s", names[fields[k].index]);
|
||||
err = -EINVAL;
|
||||
goto _err;
|
||||
|
|
|
|||
|
|
@ -567,7 +567,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
|
|||
return -EINVAL;
|
||||
}
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 1,
|
||||
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
|
||||
SND_PCM_HW_PARAM_FORMAT, SCONF_MANDATORY, &sformat);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (snd_pcm_format_linear(sformat) != 1 &&
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
|
|||
return -EINVAL;
|
||||
}
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 1,
|
||||
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
|
||||
SND_PCM_HW_PARAM_FORMAT, SCONF_MANDATORY, &sformat);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (snd_pcm_format_linear(sformat) != 1 &&
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
|
|||
return -EINVAL;
|
||||
}
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 1,
|
||||
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
|
||||
SND_PCM_HW_PARAM_FORMAT, SCONF_MANDATORY, &sformat);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (snd_pcm_format_linear(sformat) != 1) {
|
||||
|
|
|
|||
|
|
@ -185,17 +185,6 @@ typedef int snd_pcm_route_ttable_entry_t;
|
|||
|
||||
int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
|
||||
snd_pcm_stream_t stream, int mode);
|
||||
int snd_pcm_hw_open(snd_pcm_t **pcm, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode);
|
||||
int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
||||
const char *name,
|
||||
snd_pcm_route_ttable_entry_t *ttable,
|
||||
unsigned int tt_ssize,
|
||||
unsigned int tt_cused, unsigned int tt_sused,
|
||||
snd_pcm_t *slave, int close_slave);
|
||||
int snd_pcm_plug_open_hw(snd_pcm_t **pcm, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode);
|
||||
int snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, const char *sockname, const char *sname, snd_pcm_stream_t stream, int mode);
|
||||
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int fd, const char *fmt, snd_pcm_t *slave, int close_slave);
|
||||
int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode);
|
||||
|
||||
void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf);
|
||||
void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs);
|
||||
|
|
@ -518,6 +507,9 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int orde
|
|||
snd_pcm_hw_strategy_simple_choices_list_t *choices);
|
||||
#endif
|
||||
|
||||
#define SCONF_MANDATORY 1
|
||||
#define SCONF_UNCHANGED 2
|
||||
|
||||
int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
|
||||
snd_config_t **pcm_conf, unsigned int count, ...);
|
||||
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
|
|||
return -EINVAL;
|
||||
}
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 1,
|
||||
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
|
||||
SND_PCM_HW_PARAM_FORMAT, SCONF_MANDATORY, &sformat);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (snd_pcm_format_linear(sformat) != 1 &&
|
||||
|
|
|
|||
|
|
@ -738,7 +738,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
|
|||
int channels;
|
||||
slaves_id[idx] = snd_config_get_id(m);
|
||||
err = snd_pcm_slave_conf(root, m, &slaves_conf[idx], 1,
|
||||
SND_PCM_HW_PARAM_CHANNELS, 1, &channels);
|
||||
SND_PCM_HW_PARAM_CHANNELS, SCONF_MANDATORY, &channels);
|
||||
if (err < 0)
|
||||
goto _free;
|
||||
slaves_channels[idx] = channels;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ typedef struct {
|
|||
snd_pcm_t *req_slave;
|
||||
int close_slave;
|
||||
snd_pcm_t *slave;
|
||||
snd_pcm_format_t sformat;
|
||||
int schannels;
|
||||
int srate;
|
||||
snd_pcm_route_ttable_entry_t *ttable;
|
||||
unsigned int tt_ssize, tt_cused, tt_sused;
|
||||
} snd_pcm_plug_t;
|
||||
|
|
@ -399,9 +402,25 @@ static int snd_pcm_plug_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_plug_hw_refine_sprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *sparams)
|
||||
static int snd_pcm_plug_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *sparams)
|
||||
{
|
||||
snd_pcm_plug_t *plug = pcm->private_data;
|
||||
_snd_pcm_hw_params_any(sparams);
|
||||
if (plug->sformat >= 0) {
|
||||
_snd_pcm_hw_params_set_format(sparams, plug->sformat);
|
||||
_snd_pcm_hw_params_set_subformat(sparams, SND_PCM_SUBFORMAT_STD);
|
||||
}
|
||||
if (plug->schannels > 0)
|
||||
_snd_pcm_hw_param_set(sparams, SND_PCM_HW_PARAM_CHANNELS,
|
||||
plug->schannels, 0);
|
||||
if (plug->srate > 0)
|
||||
_snd_pcm_hw_param_set_minmax(sparams, SND_PCM_HW_PARAM_RATE,
|
||||
plug->srate, 0, plug->srate + 1, -1);
|
||||
if (plug->sformat >= 0 || plug->schannels > 0 || plug->srate > 0) {
|
||||
int err = snd_pcm_hw_refine(plug->req_slave, sparams);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -418,32 +437,42 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
|
|||
snd_pcm_format_t format;
|
||||
snd_interval_t t, buffer_size;
|
||||
const snd_interval_t *srate, *crate;
|
||||
snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_RATE,
|
||||
params);
|
||||
snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS,
|
||||
params);
|
||||
format_mask = snd_pcm_hw_param_get_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
sformat_mask = snd_pcm_hw_param_get_mask(sparams,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
snd_mask_none(&sfmt_mask);
|
||||
for (format = 0; format <= SND_PCM_FORMAT_LAST; snd_enum_incr(format)) {
|
||||
snd_pcm_format_t f;
|
||||
if (!snd_pcm_format_mask_test(format_mask, format))
|
||||
continue;
|
||||
if (snd_pcm_format_mask_test(sformat_mask, format))
|
||||
f = format;
|
||||
else {
|
||||
f = snd_pcm_plug_slave_format(format, sformat_mask);
|
||||
if (f == SND_PCM_FORMAT_UNKNOWN)
|
||||
if (plug->srate == -2)
|
||||
links |= SND_PCM_HW_PARBIT_RATE;
|
||||
else
|
||||
snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_RATE,
|
||||
params);
|
||||
if (plug->schannels == -2)
|
||||
links |= SND_PCM_HW_PARBIT_CHANNELS;
|
||||
else
|
||||
snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS,
|
||||
params);
|
||||
if (plug->sformat == -2)
|
||||
links |= SND_PCM_HW_PARBIT_FORMAT;
|
||||
else {
|
||||
format_mask = snd_pcm_hw_param_get_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
sformat_mask = snd_pcm_hw_param_get_mask(sparams,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
snd_mask_none(&sfmt_mask);
|
||||
for (format = 0; format <= SND_PCM_FORMAT_LAST; snd_enum_incr(format)) {
|
||||
snd_pcm_format_t f;
|
||||
if (!snd_pcm_format_mask_test(format_mask, format))
|
||||
continue;
|
||||
if (snd_pcm_format_mask_test(sformat_mask, format))
|
||||
f = format;
|
||||
else {
|
||||
f = snd_pcm_plug_slave_format(format, sformat_mask);
|
||||
if (f == SND_PCM_FORMAT_UNKNOWN)
|
||||
continue;
|
||||
}
|
||||
snd_pcm_format_mask_set(&sfmt_mask, f);
|
||||
}
|
||||
snd_pcm_format_mask_set(&sfmt_mask, f);
|
||||
}
|
||||
|
||||
err = snd_pcm_hw_param_set_mask(slave, sparams, SND_CHANGE,
|
||||
SND_PCM_HW_PARAM_FORMAT, &sfmt_mask);
|
||||
assert(err >= 0);
|
||||
err = snd_pcm_hw_param_set_mask(slave, sparams, SND_CHANGE,
|
||||
SND_PCM_HW_PARAM_FORMAT, &sfmt_mask);
|
||||
assert(err >= 0);
|
||||
}
|
||||
|
||||
if (snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_FORMAT, sparams) ||
|
||||
snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_CHANNELS, sparams) ||
|
||||
|
|
@ -453,7 +482,8 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
|
|||
_snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
|
||||
&access_mask);
|
||||
}
|
||||
if (snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams))
|
||||
if ((links & SND_PCM_HW_PARBIT_RATE) ||
|
||||
snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams))
|
||||
links |= (SND_PCM_HW_PARBIT_PERIOD_SIZE |
|
||||
SND_PCM_HW_PARBIT_BUFFER_SIZE);
|
||||
else {
|
||||
|
|
@ -476,6 +506,7 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
|
|||
snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_params_t *sparams)
|
||||
{
|
||||
snd_pcm_plug_t *plug = pcm->private_data;
|
||||
unsigned int links = (SND_PCM_HW_PARBIT_PERIOD_TIME |
|
||||
SND_PCM_HW_PARBIT_TICK_TIME);
|
||||
const snd_pcm_format_mask_t *format_mask, *sformat_mask;
|
||||
|
|
@ -487,40 +518,52 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
|
|||
const snd_interval_t *srate, *crate;
|
||||
unsigned int rate_min, srate_min;
|
||||
int rate_mindir, srate_mindir;
|
||||
format_mask = snd_pcm_hw_param_get_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
sformat_mask = snd_pcm_hw_param_get_mask(sparams,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
snd_mask_none(&fmt_mask);
|
||||
for (format = 0; format <= SND_PCM_FORMAT_LAST; snd_enum_incr(format)) {
|
||||
snd_pcm_format_t f;
|
||||
if (!snd_pcm_format_mask_test(format_mask, format))
|
||||
continue;
|
||||
if (snd_pcm_format_mask_test(sformat_mask, format))
|
||||
f = format;
|
||||
else {
|
||||
f = snd_pcm_plug_slave_format(format, sformat_mask);
|
||||
if (f == SND_PCM_FORMAT_UNKNOWN)
|
||||
|
||||
if (plug->schannels == -2)
|
||||
links |= SND_PCM_HW_PARBIT_CHANNELS;
|
||||
|
||||
if (plug->sformat == -2)
|
||||
links |= SND_PCM_HW_PARBIT_FORMAT;
|
||||
else {
|
||||
format_mask = snd_pcm_hw_param_get_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
sformat_mask = snd_pcm_hw_param_get_mask(sparams,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
snd_mask_none(&fmt_mask);
|
||||
for (format = 0; format <= SND_PCM_FORMAT_LAST; snd_enum_incr(format)) {
|
||||
snd_pcm_format_t f;
|
||||
if (!snd_pcm_format_mask_test(format_mask, format))
|
||||
continue;
|
||||
if (snd_pcm_format_mask_test(sformat_mask, format))
|
||||
f = format;
|
||||
else {
|
||||
f = snd_pcm_plug_slave_format(format, sformat_mask);
|
||||
if (f == SND_PCM_FORMAT_UNKNOWN)
|
||||
continue;
|
||||
}
|
||||
snd_pcm_format_mask_set(&fmt_mask, format);
|
||||
}
|
||||
snd_pcm_format_mask_set(&fmt_mask, format);
|
||||
}
|
||||
|
||||
err = _snd_pcm_hw_param_set_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT, &fmt_mask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* This is a temporary hack, waiting for a better solution */
|
||||
rate_min = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, &rate_mindir);
|
||||
srate_min = snd_pcm_hw_param_get_min(sparams, SND_PCM_HW_PARAM_RATE, &srate_mindir);
|
||||
if (rate_min == srate_min && srate_mindir > rate_mindir) {
|
||||
err = _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, srate_min, srate_mindir);
|
||||
err = _snd_pcm_hw_param_set_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT, &fmt_mask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams))
|
||||
if (plug->srate == -2)
|
||||
links |= SND_PCM_HW_PARBIT_RATE;
|
||||
else {
|
||||
/* This is a temporary hack, waiting for a better solution */
|
||||
rate_min = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, &rate_mindir);
|
||||
srate_min = snd_pcm_hw_param_get_min(sparams, SND_PCM_HW_PARAM_RATE, &srate_mindir);
|
||||
if (rate_min == srate_min && srate_mindir > rate_mindir) {
|
||||
err = _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, srate_min, srate_mindir);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if ((links & SND_PCM_HW_PARBIT_RATE) ||
|
||||
snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams))
|
||||
links |= (SND_PCM_HW_PARBIT_PERIOD_SIZE |
|
||||
SND_PCM_HW_PARBIT_BUFFER_SIZE);
|
||||
else {
|
||||
|
|
@ -657,6 +700,7 @@ snd_pcm_ops_t snd_pcm_plug_ops = {
|
|||
|
||||
int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
||||
const char *name,
|
||||
snd_pcm_format_t sformat, int schannels, int srate,
|
||||
snd_pcm_route_ttable_entry_t *ttable,
|
||||
unsigned int tt_ssize,
|
||||
unsigned int tt_cused, unsigned int tt_sused,
|
||||
|
|
@ -669,6 +713,9 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
|||
plug = calloc(1, sizeof(snd_pcm_plug_t));
|
||||
if (!plug)
|
||||
return -ENOMEM;
|
||||
plug->sformat = sformat;
|
||||
plug->schannels = schannels;
|
||||
plug->srate = srate;
|
||||
plug->slave = plug->req_slave = slave;
|
||||
plug->close_slave = close_slave;
|
||||
plug->ttable = ttable;
|
||||
|
|
@ -693,17 +740,7 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_pcm_plug_open_hw(snd_pcm_t **pcmp, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode)
|
||||
{
|
||||
snd_pcm_t *slave;
|
||||
int err;
|
||||
err = snd_pcm_hw_open(&slave, NULL, card, device, subdevice, stream, mode);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return snd_pcm_plug_open(pcmp, name, 0, 0, 0, 0, slave, 1);
|
||||
}
|
||||
|
||||
#define MAX_CHANNELS 32
|
||||
#define MAX_CHANNELS 64
|
||||
|
||||
int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
|
||||
snd_config_t *root, snd_config_t *conf,
|
||||
|
|
@ -716,6 +753,8 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
|
|||
snd_config_t *tt = NULL;
|
||||
snd_pcm_route_ttable_entry_t *ttable = NULL;
|
||||
unsigned int cused, sused;
|
||||
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
|
||||
int schannels = -1, srate = -1;
|
||||
snd_config_for_each(i, next, conf) {
|
||||
snd_config_t *n = snd_config_iterator_entry(i);
|
||||
const char *id = snd_config_get_id(n);
|
||||
|
|
@ -740,7 +779,10 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
|
|||
SNDERR("slave is not defined");
|
||||
return -EINVAL;
|
||||
}
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 0);
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 3,
|
||||
SND_PCM_HW_PARAM_FORMAT, SCONF_UNCHANGED, &sformat,
|
||||
SND_PCM_HW_PARAM_CHANNELS, SCONF_UNCHANGED, &schannels,
|
||||
SND_PCM_HW_PARAM_RATE, SCONF_UNCHANGED, &srate);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (tt) {
|
||||
|
|
@ -757,7 +799,8 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
|
|||
snd_config_delete(sconf);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pcm_plug_open(pcmp, name, ttable, MAX_CHANNELS, cused, sused, spcm, 1);
|
||||
err = snd_pcm_plug_open(pcmp, name, sformat, schannels, srate,
|
||||
ttable, MAX_CHANNELS, cused, sused, spcm, 1);
|
||||
if (err < 0)
|
||||
snd_pcm_close(spcm);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -556,7 +556,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
|
|||
}
|
||||
err = snd_pcm_slave_conf(root, slave, &sconf, 2,
|
||||
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
|
||||
SND_PCM_HW_PARAM_RATE, 1, &srate);
|
||||
SND_PCM_HW_PARAM_RATE, SCONF_MANDATORY, &srate);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (sformat != SND_PCM_FORMAT_UNKNOWN &&
|
||||
|
|
|
|||
|
|
@ -534,8 +534,9 @@ put_1234_4329: as_u32(dst) = bswap_32(sample) ^ 0x80; goto PUT_END;
|
|||
#endif
|
||||
|
||||
#ifdef GETS_LABELS
|
||||
static inline int32_t getS(const void *src, int src_sign, int src_wid, int src_end,
|
||||
int dst_wid)
|
||||
static inline int32_t _gets(const void *src,
|
||||
int src_sign, int src_wid, int src_end,
|
||||
int dst_wid)
|
||||
{
|
||||
int32_t s;
|
||||
switch (src_wid) {
|
||||
|
|
@ -561,8 +562,9 @@ static inline int32_t getS(const void *src, int src_sign, int src_wid, int src_e
|
|||
s -= 1U << (src_wid - 1);
|
||||
if (src_wid < dst_wid)
|
||||
return s * (1 << (dst_wid - src_wid));
|
||||
else
|
||||
else if (src_wid > dst_wid)
|
||||
return s / (1 << (src_wid - dst_wid));
|
||||
return s;
|
||||
}
|
||||
|
||||
/* src_sign src_wid src_end dst_wid */
|
||||
|
|
@ -635,62 +637,325 @@ static void *gets_labels[2 * 4 * 2 * 4] = {
|
|||
#endif
|
||||
|
||||
#ifdef GETS_END
|
||||
gets_u8_8: sample = getS(src, 0, 8, 0, 8); goto GETS_END;
|
||||
gets_u8_16: sample = getS(src, 0, 8, 0, 16); goto GETS_END;
|
||||
gets_u8_24: sample = getS(src, 0, 8, 0, 24); goto GETS_END;
|
||||
gets_u8_32: sample = getS(src, 0, 8, 0, 32); goto GETS_END;
|
||||
gets_u16h_8: sample = getS(src, 0, 16, 0, 8); goto GETS_END;
|
||||
gets_u16h_16: sample = getS(src, 0, 16, 0, 16); goto GETS_END;
|
||||
gets_u16h_24: sample = getS(src, 0, 16, 0, 24); goto GETS_END;
|
||||
gets_u16h_32: sample = getS(src, 0, 16, 0, 32); goto GETS_END;
|
||||
gets_u16s_8: sample = getS(src, 0, 16, 1, 8); goto GETS_END;
|
||||
gets_u16s_16: sample = getS(src, 0, 16, 1, 16); goto GETS_END;
|
||||
gets_u16s_24: sample = getS(src, 0, 16, 1, 24); goto GETS_END;
|
||||
gets_u16s_32: sample = getS(src, 0, 16, 1, 32); goto GETS_END;
|
||||
gets_u24h_8: sample = getS(src, 0, 24, 0, 8); goto GETS_END;
|
||||
gets_u24h_16: sample = getS(src, 0, 24, 0, 16); goto GETS_END;
|
||||
gets_u24h_24: sample = getS(src, 0, 24, 0, 24); goto GETS_END;
|
||||
gets_u24h_32: sample = getS(src, 0, 24, 0, 32); goto GETS_END;
|
||||
gets_u24s_8: sample = getS(src, 0, 24, 1, 8); goto GETS_END;
|
||||
gets_u24s_16: sample = getS(src, 0, 24, 1, 16); goto GETS_END;
|
||||
gets_u24s_24: sample = getS(src, 0, 24, 1, 24); goto GETS_END;
|
||||
gets_u24s_32: sample = getS(src, 0, 24, 1, 32); goto GETS_END;
|
||||
gets_u32h_8: sample = getS(src, 0, 32, 0, 8); goto GETS_END;
|
||||
gets_u32h_16: sample = getS(src, 0, 32, 0, 16); goto GETS_END;
|
||||
gets_u32h_24: sample = getS(src, 0, 32, 0, 24); goto GETS_END;
|
||||
gets_u32h_32: sample = getS(src, 0, 32, 0, 32); goto GETS_END;
|
||||
gets_u32s_8: sample = getS(src, 0, 32, 1, 8); goto GETS_END;
|
||||
gets_u32s_16: sample = getS(src, 0, 32, 1, 16); goto GETS_END;
|
||||
gets_u32s_24: sample = getS(src, 0, 32, 1, 24); goto GETS_END;
|
||||
gets_u32s_32: sample = getS(src, 0, 32, 1, 32); goto GETS_END;
|
||||
gets_s8_8: sample = getS(src, 1, 8, 0, 8); goto GETS_END;
|
||||
gets_s8_16: sample = getS(src, 1, 8, 0, 16); goto GETS_END;
|
||||
gets_s8_24: sample = getS(src, 1, 8, 0, 24); goto GETS_END;
|
||||
gets_s8_32: sample = getS(src, 1, 8, 0, 32); goto GETS_END;
|
||||
gets_s16h_8: sample = getS(src, 1, 16, 0, 8); goto GETS_END;
|
||||
gets_s16h_16: sample = getS(src, 1, 16, 0, 16); goto GETS_END;
|
||||
gets_s16h_24: sample = getS(src, 1, 16, 0, 24); goto GETS_END;
|
||||
gets_s16h_32: sample = getS(src, 1, 16, 0, 32); goto GETS_END;
|
||||
gets_s16s_8: sample = getS(src, 1, 16, 1, 8); goto GETS_END;
|
||||
gets_s16s_16: sample = getS(src, 1, 16, 1, 16); goto GETS_END;
|
||||
gets_s16s_24: sample = getS(src, 1, 16, 1, 24); goto GETS_END;
|
||||
gets_s16s_32: sample = getS(src, 1, 16, 1, 32); goto GETS_END;
|
||||
gets_s24h_8: sample = getS(src, 1, 24, 0, 8); goto GETS_END;
|
||||
gets_s24h_16: sample = getS(src, 1, 24, 0, 16); goto GETS_END;
|
||||
gets_s24h_24: sample = getS(src, 1, 24, 0, 24); goto GETS_END;
|
||||
gets_s24h_32: sample = getS(src, 1, 24, 0, 32); goto GETS_END;
|
||||
gets_s24s_8: sample = getS(src, 1, 24, 1, 8); goto GETS_END;
|
||||
gets_s24s_16: sample = getS(src, 1, 24, 1, 16); goto GETS_END;
|
||||
gets_s24s_24: sample = getS(src, 1, 24, 1, 24); goto GETS_END;
|
||||
gets_s24s_32: sample = getS(src, 1, 24, 1, 32); goto GETS_END;
|
||||
gets_s32h_8: sample = getS(src, 1, 32, 0, 8); goto GETS_END;
|
||||
gets_s32h_16: sample = getS(src, 1, 32, 0, 16); goto GETS_END;
|
||||
gets_s32h_24: sample = getS(src, 1, 32, 0, 24); goto GETS_END;
|
||||
gets_s32h_32: sample = getS(src, 1, 32, 0, 32); goto GETS_END;
|
||||
gets_s32s_8: sample = getS(src, 1, 32, 1, 8); goto GETS_END;
|
||||
gets_s32s_16: sample = getS(src, 1, 32, 1, 16); goto GETS_END;
|
||||
gets_s32s_24: sample = getS(src, 1, 32, 1, 24); goto GETS_END;
|
||||
gets_s32s_32: sample = getS(src, 1, 32, 1, 32); goto GETS_END;
|
||||
gets_u8_8: sample = _gets(src, 0, 8, 0, 8); goto GETS_END;
|
||||
gets_u8_16: sample = _gets(src, 0, 8, 0, 16); goto GETS_END;
|
||||
gets_u8_24: sample = _gets(src, 0, 8, 0, 24); goto GETS_END;
|
||||
gets_u8_32: sample = _gets(src, 0, 8, 0, 32); goto GETS_END;
|
||||
gets_u16h_8: sample = _gets(src, 0, 16, 0, 8); goto GETS_END;
|
||||
gets_u16h_16: sample = _gets(src, 0, 16, 0, 16); goto GETS_END;
|
||||
gets_u16h_24: sample = _gets(src, 0, 16, 0, 24); goto GETS_END;
|
||||
gets_u16h_32: sample = _gets(src, 0, 16, 0, 32); goto GETS_END;
|
||||
gets_u16s_8: sample = _gets(src, 0, 16, 1, 8); goto GETS_END;
|
||||
gets_u16s_16: sample = _gets(src, 0, 16, 1, 16); goto GETS_END;
|
||||
gets_u16s_24: sample = _gets(src, 0, 16, 1, 24); goto GETS_END;
|
||||
gets_u16s_32: sample = _gets(src, 0, 16, 1, 32); goto GETS_END;
|
||||
gets_u24h_8: sample = _gets(src, 0, 24, 0, 8); goto GETS_END;
|
||||
gets_u24h_16: sample = _gets(src, 0, 24, 0, 16); goto GETS_END;
|
||||
gets_u24h_24: sample = _gets(src, 0, 24, 0, 24); goto GETS_END;
|
||||
gets_u24h_32: sample = _gets(src, 0, 24, 0, 32); goto GETS_END;
|
||||
gets_u24s_8: sample = _gets(src, 0, 24, 1, 8); goto GETS_END;
|
||||
gets_u24s_16: sample = _gets(src, 0, 24, 1, 16); goto GETS_END;
|
||||
gets_u24s_24: sample = _gets(src, 0, 24, 1, 24); goto GETS_END;
|
||||
gets_u24s_32: sample = _gets(src, 0, 24, 1, 32); goto GETS_END;
|
||||
gets_u32h_8: sample = _gets(src, 0, 32, 0, 8); goto GETS_END;
|
||||
gets_u32h_16: sample = _gets(src, 0, 32, 0, 16); goto GETS_END;
|
||||
gets_u32h_24: sample = _gets(src, 0, 32, 0, 24); goto GETS_END;
|
||||
gets_u32h_32: sample = _gets(src, 0, 32, 0, 32); goto GETS_END;
|
||||
gets_u32s_8: sample = _gets(src, 0, 32, 1, 8); goto GETS_END;
|
||||
gets_u32s_16: sample = _gets(src, 0, 32, 1, 16); goto GETS_END;
|
||||
gets_u32s_24: sample = _gets(src, 0, 32, 1, 24); goto GETS_END;
|
||||
gets_u32s_32: sample = _gets(src, 0, 32, 1, 32); goto GETS_END;
|
||||
gets_s8_8: sample = _gets(src, 1, 8, 0, 8); goto GETS_END;
|
||||
gets_s8_16: sample = _gets(src, 1, 8, 0, 16); goto GETS_END;
|
||||
gets_s8_24: sample = _gets(src, 1, 8, 0, 24); goto GETS_END;
|
||||
gets_s8_32: sample = _gets(src, 1, 8, 0, 32); goto GETS_END;
|
||||
gets_s16h_8: sample = _gets(src, 1, 16, 0, 8); goto GETS_END;
|
||||
gets_s16h_16: sample = _gets(src, 1, 16, 0, 16); goto GETS_END;
|
||||
gets_s16h_24: sample = _gets(src, 1, 16, 0, 24); goto GETS_END;
|
||||
gets_s16h_32: sample = _gets(src, 1, 16, 0, 32); goto GETS_END;
|
||||
gets_s16s_8: sample = _gets(src, 1, 16, 1, 8); goto GETS_END;
|
||||
gets_s16s_16: sample = _gets(src, 1, 16, 1, 16); goto GETS_END;
|
||||
gets_s16s_24: sample = _gets(src, 1, 16, 1, 24); goto GETS_END;
|
||||
gets_s16s_32: sample = _gets(src, 1, 16, 1, 32); goto GETS_END;
|
||||
gets_s24h_8: sample = _gets(src, 1, 24, 0, 8); goto GETS_END;
|
||||
gets_s24h_16: sample = _gets(src, 1, 24, 0, 16); goto GETS_END;
|
||||
gets_s24h_24: sample = _gets(src, 1, 24, 0, 24); goto GETS_END;
|
||||
gets_s24h_32: sample = _gets(src, 1, 24, 0, 32); goto GETS_END;
|
||||
gets_s24s_8: sample = _gets(src, 1, 24, 1, 8); goto GETS_END;
|
||||
gets_s24s_16: sample = _gets(src, 1, 24, 1, 16); goto GETS_END;
|
||||
gets_s24s_24: sample = _gets(src, 1, 24, 1, 24); goto GETS_END;
|
||||
gets_s24s_32: sample = _gets(src, 1, 24, 1, 32); goto GETS_END;
|
||||
gets_s32h_8: sample = _gets(src, 1, 32, 0, 8); goto GETS_END;
|
||||
gets_s32h_16: sample = _gets(src, 1, 32, 0, 16); goto GETS_END;
|
||||
gets_s32h_24: sample = _gets(src, 1, 32, 0, 24); goto GETS_END;
|
||||
gets_s32h_32: sample = _gets(src, 1, 32, 0, 32); goto GETS_END;
|
||||
gets_s32s_8: sample = _gets(src, 1, 32, 1, 8); goto GETS_END;
|
||||
gets_s32s_16: sample = _gets(src, 1, 32, 1, 16); goto GETS_END;
|
||||
gets_s32s_24: sample = _gets(src, 1, 32, 1, 24); goto GETS_END;
|
||||
gets_s32s_32: sample = _gets(src, 1, 32, 1, 32); goto GETS_END;
|
||||
#endif
|
||||
|
||||
#ifdef NORMS_LABELS
|
||||
static inline void _norms(const void *src, void *dst,
|
||||
int src_wid,
|
||||
int dst_sign, int dst_wid, int dst_end)
|
||||
{
|
||||
int32_t s;
|
||||
switch (src_wid) {
|
||||
case 8:
|
||||
s = *(int8_t*)src;
|
||||
if (s >= 0x7f)
|
||||
goto _min;
|
||||
else if (s <= -0x80)
|
||||
goto _max;
|
||||
break;
|
||||
case 16:
|
||||
s = *(int16_t*)src;
|
||||
if (s >= 0x7fff)
|
||||
goto _min;
|
||||
else if (s <= -0x8000)
|
||||
goto _max;
|
||||
break;
|
||||
case 24:
|
||||
s = *(int32_t*)src;
|
||||
if (s >= 0x7fffff)
|
||||
goto _min;
|
||||
else if (s <= -0x800000)
|
||||
goto _max;
|
||||
break;
|
||||
case 32:
|
||||
{
|
||||
int64_t s64;
|
||||
s64 = *(int64_t*)src;
|
||||
if (s64 >= 0x7fffffff)
|
||||
goto _min;
|
||||
else if (s64 <= -0x80000000)
|
||||
goto _max;
|
||||
s = s64;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
if (src_wid < dst_wid) {
|
||||
unsigned int bits = dst_wid - src_wid;
|
||||
s *= 1 << bits;
|
||||
} else if (src_wid > dst_wid) {
|
||||
unsigned int bits = src_wid - dst_wid;
|
||||
s = (s + (1 << (bits - 1)))/ (1 << bits);
|
||||
}
|
||||
if (!dst_sign)
|
||||
s += (1U << (dst_wid - 1));
|
||||
switch (dst_wid) {
|
||||
case 8:
|
||||
*(u_int8_t*)dst = s;
|
||||
break;
|
||||
case 16:
|
||||
if (dst_end)
|
||||
s = bswap_16(s);
|
||||
*(u_int16_t*)dst = s;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
if (dst_end)
|
||||
s = bswap_32(s);
|
||||
*(u_int32_t*)dst = s;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
_min:
|
||||
switch (dst_wid) {
|
||||
case 8:
|
||||
if (dst_sign)
|
||||
*(u_int8_t*)dst = 0x80;
|
||||
else
|
||||
*(u_int8_t*)dst = 0;
|
||||
break;
|
||||
case 16:
|
||||
if (dst_sign)
|
||||
*(u_int16_t*)dst = dst_end ? 0x0080 : 0x8000;
|
||||
else
|
||||
*(u_int16_t*)dst = 0;
|
||||
break;
|
||||
case 24:
|
||||
if (dst_sign)
|
||||
*(u_int32_t*)dst = dst_end ? 0x00008000 : 0x00800000;
|
||||
else
|
||||
*(u_int32_t*)dst = 0;
|
||||
break;
|
||||
case 32:
|
||||
if (dst_sign)
|
||||
*(u_int32_t*)dst = dst_end ? 0x00000080 : 0x80000000;
|
||||
else
|
||||
*(u_int32_t*)dst = 0;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
_max:
|
||||
switch (dst_wid) {
|
||||
case 8:
|
||||
if (dst_sign)
|
||||
*(u_int8_t*)dst = 0x7f;
|
||||
else
|
||||
*(u_int8_t*)dst = 0xff;
|
||||
break;
|
||||
case 16:
|
||||
if (dst_sign)
|
||||
*(u_int16_t*)dst = dst_end ? 0xff7f : 0x7fff;
|
||||
else
|
||||
*(u_int16_t*)dst = 0;
|
||||
break;
|
||||
case 24:
|
||||
if (dst_sign)
|
||||
*(u_int32_t*)dst = dst_end ? 0xffff7f00 : 0x007fffff;
|
||||
else
|
||||
*(u_int32_t*)dst = 0;
|
||||
break;
|
||||
case 32:
|
||||
if (dst_sign)
|
||||
*(u_int32_t*)dst = dst_end ? 0xffffff7f : 0x7fffffff;
|
||||
else
|
||||
*(u_int32_t*)dst = 0;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* src_wid dst_sign dst_wid dst_end */
|
||||
static void *norms_labels[4 * 2 * 4 * 2] = {
|
||||
&&norms_8_u8, /* s8 -> u8 */
|
||||
&&norms_8_u8, /* s8 -> u8 */
|
||||
&&norms_8_u16h, /* s8 -> u16h */
|
||||
&&norms_8_u16s, /* s8 -> u16s */
|
||||
&&norms_8_u24h, /* s8 -> u24h */
|
||||
&&norms_8_u24s, /* s8 -> u24s */
|
||||
&&norms_8_u32h, /* s8 -> u32h */
|
||||
&&norms_8_u32s, /* s8 -> u32s */
|
||||
&&norms_8_s8, /* s8 -> s8 */
|
||||
&&norms_8_s8, /* s8 -> s8 */
|
||||
&&norms_8_s16h, /* s8 -> s16h */
|
||||
&&norms_8_s16s, /* s8 -> s16s */
|
||||
&&norms_8_s24h, /* s8 -> s24h */
|
||||
&&norms_8_s24s, /* s8 -> s24s */
|
||||
&&norms_8_s32h, /* s8 -> s32h */
|
||||
&&norms_8_s32s, /* s8 -> s32s */
|
||||
&&norms_16_u8, /* s16 -> u8 */
|
||||
&&norms_16_u8, /* s16 -> u8 */
|
||||
&&norms_16_u16h, /* s16 -> u16h */
|
||||
&&norms_16_u16s, /* s16 -> u16s */
|
||||
&&norms_16_u24h, /* s16 -> u24h */
|
||||
&&norms_16_u24s, /* s16 -> u24s */
|
||||
&&norms_16_u32h, /* s16 -> u32h */
|
||||
&&norms_16_u32s, /* s16 -> u32s */
|
||||
&&norms_16_s8, /* s16 -> s8 h*/
|
||||
&&norms_16_s8, /* s16 -> s8 */
|
||||
&&norms_16_s16h, /* s16 -> s16h */
|
||||
&&norms_16_s16s, /* s16 -> s16s */
|
||||
&&norms_16_s24h, /* s16 -> s24h */
|
||||
&&norms_16_s24s, /* s16 -> s24s */
|
||||
&&norms_16_s32h, /* s16 -> s32h */
|
||||
&&norms_16_s32s, /* s16 -> s32s */
|
||||
&&norms_24_u8, /* s24 -> u8 */
|
||||
&&norms_24_u8, /* s24 -> u8 */
|
||||
&&norms_24_u16h, /* s24 -> u16h */
|
||||
&&norms_24_u16s, /* s24 -> u16s */
|
||||
&&norms_24_u24h, /* s24 -> u24h */
|
||||
&&norms_24_u24s, /* s24 -> u24s */
|
||||
&&norms_24_u32h, /* s24 -> u32h */
|
||||
&&norms_24_u32s, /* s24 -> u32s */
|
||||
&&norms_24_s8, /* s24 -> s8 */
|
||||
&&norms_24_s8, /* s24 -> s8 */
|
||||
&&norms_24_s16h, /* s24 -> s16h */
|
||||
&&norms_24_s16s, /* s24 -> s16s */
|
||||
&&norms_24_s24h, /* s24 -> s24h */
|
||||
&&norms_24_s24s, /* s24 -> s24s */
|
||||
&&norms_24_s32h, /* s24 -> s32h */
|
||||
&&norms_24_s32s, /* s24 -> s32s */
|
||||
&&norms_32_u8, /* s32 -> u8 */
|
||||
&&norms_32_u8, /* s32 -> u8 */
|
||||
&&norms_32_u16h, /* s32 -> u16h */
|
||||
&&norms_32_u16s, /* s32 -> u16s */
|
||||
&&norms_32_u24h, /* s32 -> u24h */
|
||||
&&norms_32_u24s, /* s32 -> u24s */
|
||||
&&norms_32_u32h, /* s32 -> u32h */
|
||||
&&norms_32_u32s, /* s32 -> u32s */
|
||||
&&norms_32_s8, /* s32 -> s8 */
|
||||
&&norms_32_s8, /* s32 -> s8 */
|
||||
&&norms_32_s16h, /* s32 -> s16h */
|
||||
&&norms_32_s16s, /* s32 -> s16s */
|
||||
&&norms_32_s24h, /* s32 -> s24h */
|
||||
&&norms_32_s24s, /* s32 -> s24s */
|
||||
&&norms_32_s32h, /* s32 -> s32h */
|
||||
&&norms_32_s32s, /* s32 -> s32s */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef NORMS_END
|
||||
norms_8_u8: _norms(src, dst, 8, 0, 8, 0); goto NORMS_END;
|
||||
norms_8_u16h: _norms(src, dst, 8, 0, 16, 0); goto NORMS_END;
|
||||
norms_8_u16s: _norms(src, dst, 8, 0, 16, 1); goto NORMS_END;
|
||||
norms_8_u24h: _norms(src, dst, 8, 0, 24, 0); goto NORMS_END;
|
||||
norms_8_u24s: _norms(src, dst, 8, 0, 24, 1); goto NORMS_END;
|
||||
norms_8_u32h: _norms(src, dst, 8, 0, 32, 0); goto NORMS_END;
|
||||
norms_8_u32s: _norms(src, dst, 8, 0, 32, 1); goto NORMS_END;
|
||||
norms_8_s8: _norms(src, dst, 8, 1, 8, 0); goto NORMS_END;
|
||||
norms_8_s16h: _norms(src, dst, 8, 1, 16, 0); goto NORMS_END;
|
||||
norms_8_s16s: _norms(src, dst, 8, 1, 16, 1); goto NORMS_END;
|
||||
norms_8_s24h: _norms(src, dst, 8, 1, 24, 0); goto NORMS_END;
|
||||
norms_8_s24s: _norms(src, dst, 8, 1, 24, 1); goto NORMS_END;
|
||||
norms_8_s32h: _norms(src, dst, 8, 1, 32, 0); goto NORMS_END;
|
||||
norms_8_s32s: _norms(src, dst, 8, 1, 32, 1); goto NORMS_END;
|
||||
norms_16_u8: _norms(src, dst, 16, 0, 8, 0); goto NORMS_END;
|
||||
norms_16_u16h: _norms(src, dst, 16, 0, 16, 0); goto NORMS_END;
|
||||
norms_16_u16s: _norms(src, dst, 16, 0, 16, 1); goto NORMS_END;
|
||||
norms_16_u24h: _norms(src, dst, 16, 0, 24, 0); goto NORMS_END;
|
||||
norms_16_u24s: _norms(src, dst, 16, 0, 24, 1); goto NORMS_END;
|
||||
norms_16_u32h: _norms(src, dst, 16, 0, 32, 0); goto NORMS_END;
|
||||
norms_16_u32s: _norms(src, dst, 16, 0, 32, 1); goto NORMS_END;
|
||||
norms_16_s8: _norms(src, dst, 16, 1, 8, 0); goto NORMS_END;
|
||||
norms_16_s16h: _norms(src, dst, 16, 1, 16, 0); goto NORMS_END;
|
||||
norms_16_s16s: _norms(src, dst, 16, 1, 16, 1); goto NORMS_END;
|
||||
norms_16_s24h: _norms(src, dst, 16, 1, 24, 0); goto NORMS_END;
|
||||
norms_16_s24s: _norms(src, dst, 16, 1, 24, 1); goto NORMS_END;
|
||||
norms_16_s32h: _norms(src, dst, 16, 1, 32, 0); goto NORMS_END;
|
||||
norms_16_s32s: _norms(src, dst, 16, 1, 32, 1); goto NORMS_END;
|
||||
norms_24_u8: _norms(src, dst, 24, 0, 8, 0); goto NORMS_END;
|
||||
norms_24_u16h: _norms(src, dst, 24, 0, 16, 0); goto NORMS_END;
|
||||
norms_24_u16s: _norms(src, dst, 24, 0, 16, 1); goto NORMS_END;
|
||||
norms_24_u24h: _norms(src, dst, 24, 0, 24, 0); goto NORMS_END;
|
||||
norms_24_u24s: _norms(src, dst, 24, 0, 24, 1); goto NORMS_END;
|
||||
norms_24_u32h: _norms(src, dst, 24, 0, 32, 0); goto NORMS_END;
|
||||
norms_24_u32s: _norms(src, dst, 24, 0, 32, 1); goto NORMS_END;
|
||||
norms_24_s8: _norms(src, dst, 24, 1, 8, 0); goto NORMS_END;
|
||||
norms_24_s16h: _norms(src, dst, 24, 1, 16, 0); goto NORMS_END;
|
||||
norms_24_s16s: _norms(src, dst, 24, 1, 16, 1); goto NORMS_END;
|
||||
norms_24_s24h: _norms(src, dst, 24, 1, 24, 0); goto NORMS_END;
|
||||
norms_24_s24s: _norms(src, dst, 24, 1, 24, 1); goto NORMS_END;
|
||||
norms_24_s32h: _norms(src, dst, 24, 1, 32, 0); goto NORMS_END;
|
||||
norms_24_s32s: _norms(src, dst, 24, 1, 32, 1); goto NORMS_END;
|
||||
norms_32_u8: _norms(src, dst, 32, 0, 8, 0); goto NORMS_END;
|
||||
norms_32_u16h: _norms(src, dst, 32, 0, 16, 0); goto NORMS_END;
|
||||
norms_32_u16s: _norms(src, dst, 32, 0, 16, 1); goto NORMS_END;
|
||||
norms_32_u24h: _norms(src, dst, 32, 0, 24, 0); goto NORMS_END;
|
||||
norms_32_u24s: _norms(src, dst, 32, 0, 24, 1); goto NORMS_END;
|
||||
norms_32_u32h: _norms(src, dst, 32, 0, 32, 0); goto NORMS_END;
|
||||
norms_32_u32s: _norms(src, dst, 32, 0, 32, 1); goto NORMS_END;
|
||||
norms_32_s8: _norms(src, dst, 32, 1, 8, 0); goto NORMS_END;
|
||||
norms_32_s16h: _norms(src, dst, 32, 1, 16, 0); goto NORMS_END;
|
||||
norms_32_s16s: _norms(src, dst, 32, 1, 16, 1); goto NORMS_END;
|
||||
norms_32_s24h: _norms(src, dst, 32, 1, 24, 0); goto NORMS_END;
|
||||
norms_32_s24s: _norms(src, dst, 32, 1, 24, 1); goto NORMS_END;
|
||||
norms_32_s32h: _norms(src, dst, 32, 1, 32, 0); goto NORMS_END;
|
||||
norms_32_s32s: _norms(src, dst, 32, 1, 32, 1); goto NORMS_END;
|
||||
#endif
|
||||
|
||||
#undef as_u8
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue