From: Abramo Bagnara Date: Sat, 7 Jul 2001 15:53:20 +0000 (+0000) Subject: Permit to PCM plug configuration to specify unchanged parameters. Added support for... X-Git-Tag: v1.0.3~754 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=fcd164e6229c7dd9f58a3d1d87b1ea9bf5301f7d;p=alsa-lib.git Permit to PCM plug configuration to specify unchanged parameters. Added support for RT signals to async interface. Added ops for PCM mix. --- diff --git a/doc/asoundrc.doc b/doc/asoundrc.doc index e027ea4a..fa354fd8 100644 --- a/doc/asoundrc.doc +++ b/doc/asoundrc.doc @@ -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) diff --git a/include/local.h b/include/local.h index 7e1a526d..1b100375 100644 --- a/include/local.h +++ b/include/local.h @@ -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, diff --git a/src/async.c b/src/async.c index 180866b5..7c891f49 100644 --- a/src/async.c +++ b/src/async.c @@ -22,6 +22,22 @@ #include "control/control_local.h" #include +#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; diff --git a/src/control/control.c b/src/control/control.c index c43025d8..44f1742d 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -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; diff --git a/src/control/control_hw.c b/src/control/control_hw.c index 694517f3..5374c9a2 100644 --- a/src/control/control_hw.c +++ b/src/control/control_hw.c @@ -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; diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 2b0ed1a1..aea129a9 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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; diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c index f9baec0c..b8f06112 100644 --- a/src/pcm/pcm_adpcm.c +++ b/src/pcm/pcm_adpcm.c @@ -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 && diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c index 04a886d2..230bf947 100644 --- a/src/pcm/pcm_alaw.c +++ b/src/pcm/pcm_alaw.c @@ -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 && diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c index f1b9c92f..6bbe90fe 100644 --- a/src/pcm/pcm_linear.c +++ b/src/pcm/pcm_linear.c @@ -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) { diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 7956ffde..6332d491 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -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, ...); diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c index 19655948..a8a32efa 100644 --- a/src/pcm/pcm_mulaw.c +++ b/src/pcm/pcm_mulaw.c @@ -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 && diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index 29da1e42..de59198b 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -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; diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 6d322977..eea5d113 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -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; diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index d720379e..fd8030c7 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -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 && diff --git a/src/pcm/plugin_ops.h b/src/pcm/plugin_ops.h index 09551909..e40887c3 100644 --- a/src/pcm/plugin_ops.h +++ b/src/pcm/plugin_ops.h @@ -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