Allow partial build with selected components

Add --enable-* and --with-pcm-plugins configure options for partial builds.

User can choose the core components (pcm, mixer, rawmidi, hwdep, seq, instr)
via --enable-xxx or --disable-xxx option.  As default, all components are
enabled.

The PCM plugins to build can be selected via --with-pcm-plugins option.
For example, to build only rate and linear plugin, pass
  --with-pcm-plugins=rate,linear
Passing "all" will select all plugins (it's the default value).

The plug plugin will select linear and copy plugins automatically.
The other auto conversions of plug plugin are enabled only when the
corresponding plugin is selected.
This commit is contained in:
Takashi Iwai 2005-11-30 11:38:24 +00:00
parent 79c3d0a1ef
commit db1e39a4e8
8 changed files with 369 additions and 54 deletions

View file

@ -172,12 +172,27 @@ static snd_pcm_format_t linear_preferred_formats[] = {
#endif
};
static snd_pcm_format_t nonlinear_preferred_formats[] = {
SND_PCM_FORMAT_MU_LAW,
SND_PCM_FORMAT_A_LAW,
SND_PCM_FORMAT_IMA_ADPCM,
};
#if defined(BUILD_PCM_PLUGIN_MULAW) || \
defined(BUILD_PCM_PLUGIN_ALAW) || \
defined(BUILD_PCM_PLUGIN_ADPCM)
#define BUILD_PCM_NONLINEAR
#endif
#ifdef BUILD_PCM_NONLINEAR
static snd_pcm_format_t nonlinear_preferred_formats[] = {
#ifdef BUILD_PCM_PLUGIN_MULAW
SND_PCM_FORMAT_MU_LAW,
#endif
#ifdef BUILD_PCM_PLUGIN_ALAW
SND_PCM_FORMAT_A_LAW,
#endif
#ifdef BUILD_PCM_PLUGIN_ADPCM
SND_PCM_FORMAT_IMA_ADPCM,
#endif
};
#endif
#ifdef BUILD_PCM_PLUGIN_LFLOAT
static snd_pcm_format_t float_preferred_formats[] = {
#ifdef SND_LITTLE_ENDIAN
SND_PCM_FORMAT_FLOAT_LE,
@ -191,6 +206,7 @@ static snd_pcm_format_t float_preferred_formats[] = {
SND_PCM_FORMAT_FLOAT64_LE,
#endif
};
#endif
static char linear_format_widths[32] = {
0, 0, 0, 0, 0, 0, 0, 1,
@ -226,16 +242,28 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
int w, w1, u, e;
snd_pcm_format_t f;
snd_pcm_format_mask_t lin = { SND_PCM_FMTBIT_LINEAR };
snd_pcm_format_mask_t fl = { SND_PCM_FMTBIT_FLOAT };
snd_pcm_format_mask_t fl = {
#ifdef BUILD_PCM_PLUGIN_LFLOAT
SND_PCM_FMTBIT_FLOAT
#else
{ 0 }
#endif
};
if (snd_pcm_format_mask_test(format_mask, format))
return format;
if (!snd_pcm_format_mask_test(&lin, format) &&
!snd_pcm_format_mask_test(&fl, format)) {
unsigned int i;
switch (format) {
#ifdef BUILD_PCM_PLUGIN_MULAW
case SND_PCM_FORMAT_MU_LAW:
#endif
#ifdef BUILD_PCM_PLUGIN_ALAW
case SND_PCM_FORMAT_A_LAW:
#endif
#ifdef BUILD_PCM_PLUGIN_ADPCM
case SND_PCM_FORMAT_IMA_ADPCM:
#endif
for (i = 0; i < sizeof(linear_preferred_formats) / sizeof(linear_preferred_formats[0]); ++i) {
snd_pcm_format_t f = linear_preferred_formats[i];
if (snd_pcm_format_mask_test(format_mask, f))
@ -250,14 +278,17 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
snd_mask_intersect(&lin, format_mask);
snd_mask_intersect(&fl, format_mask);
if (snd_mask_empty(&lin) && snd_mask_empty(&fl)) {
#ifdef BUILD_PCM_NONLINEAR
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];
if (snd_pcm_format_mask_test(format_mask, f))
return f;
}
#endif
return SND_PCM_FORMAT_UNKNOWN;
}
#ifdef BUILD_PCM_PLUGIN_LFLOAT
if (snd_pcm_format_float(format)) {
if (snd_pcm_format_mask_test(&fl, format)) {
unsigned int i;
@ -270,13 +301,17 @@ static snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, const
w = 32;
u = 0;
e = snd_pcm_format_big_endian(format);
} else if (snd_mask_empty(&lin)) {
} else
#endif
if (snd_mask_empty(&lin)) {
#ifdef BUILD_PCM_PLUGIN_LFLOAT
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;
}
#endif
return SND_PCM_FORMAT_UNKNOWN;
} else {
w = snd_pcm_format_width(format);
@ -320,6 +355,7 @@ typedef struct {
} snd_pcm_plug_params_t;
#endif
#ifdef BUILD_PCM_PLUGIN_RATE
static int snd_pcm_plug_change_rate(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_plug_params_t *clt, snd_pcm_plug_params_t *slv)
{
snd_pcm_plug_t *plug = pcm->private_data;
@ -336,7 +372,9 @@ static int snd_pcm_plug_change_rate(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_plu
slv->format = clt->format;
return 1;
}
#endif
#ifdef BUILD_PCM_PLUGIN_ROUTE
static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_plug_params_t *clt, snd_pcm_plug_params_t *slv)
{
snd_pcm_plug_t *plug = pcm->private_data;
@ -437,6 +475,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
slv->format = clt->format;
return 1;
}
#endif
static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_plug_params_t *clt, snd_pcm_plug_params_t *slv)
{
@ -446,30 +485,47 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
int (*f)(snd_pcm_t **_pcm, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
if (snd_pcm_format_linear(slv->format)) {
/* Conversion is done in another plugin */
if (clt->format == slv->format ||
clt->rate != slv->rate ||
clt->channels != slv->channels)
return 0;
if (clt->format == slv->format) {
#ifdef BUILD_PCM_PLUGIN_RATE
if (clt->rate != slv->rate)
return 0;
#endif
#ifdef BUILD_PCM_PLUGIN_ROUTE
if (clt->channels != slv->channels)
return 0;
#endif
}
cfmt = clt->format;
switch (clt->format) {
#ifdef BUILD_PCM_PLUGIN_MULAW
case SND_PCM_FORMAT_MU_LAW:
f = snd_pcm_mulaw_open;
break;
#endif
#ifdef BUILD_PCM_PLUGIN_ALAW
case SND_PCM_FORMAT_A_LAW:
f = snd_pcm_alaw_open;
break;
#endif
#ifdef BUILD_PCM_PLUGIN_ADPCM
case SND_PCM_FORMAT_IMA_ADPCM:
f = snd_pcm_adpcm_open;
break;
#endif
default:
if (snd_pcm_format_float(clt->format)) {
#ifdef BUILD_PCM_PLUGIN_LFLOAT
if (snd_pcm_format_float(clt->format))
f = snd_pcm_lfloat_open;
} else {
else
#endif
{
assert(snd_pcm_format_linear(clt->format));
f = snd_pcm_linear_open;
}
break;
}
#ifdef BUILD_PCM_PLUGIN_LFLOAT
} else if (snd_pcm_format_float(slv->format)) {
/* Conversion is done in another plugin */
if (clt->format == slv->format &&
@ -483,6 +539,8 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
assert(0); /* TODO */
return -EINVAL;
}
#endif
#ifdef BUILD_PCM_NONLINEAR
} else {
/* No conversion is needed */
if (clt->format == slv->format &&
@ -490,15 +548,21 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
clt->channels == clt->channels)
return 0;
switch (slv->format) {
#ifdef BUILD_PCM_PLUGIN_MULAW
case SND_PCM_FORMAT_MU_LAW:
f = snd_pcm_mulaw_open;
break;
#endif
#ifdef BUILD_PCM_PLUGIN_ALAW
case SND_PCM_FORMAT_A_LAW:
f = snd_pcm_alaw_open;
break;
#endif
#ifdef BUILD_PCM_PLUGIN_ADPCM
case SND_PCM_FORMAT_IMA_ADPCM:
f = snd_pcm_adpcm_open;
break;
#endif
default:
assert(0);
return -EINVAL;
@ -507,6 +571,7 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
cfmt = clt->format;
else
cfmt = SND_PCM_FORMAT_S16;
#endif /* NONLINEAR */
}
err = f(new, NULL, slv->format, plug->gen.slave, plug->gen.slave != plug->req_slave);
if (err < 0)
@ -536,9 +601,15 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
snd_pcm_plug_t *plug = pcm->private_data;
static int (*funcs[])(snd_pcm_t *_pcm, snd_pcm_t **new, snd_pcm_plug_params_t *s, snd_pcm_plug_params_t *d) = {
snd_pcm_plug_change_format,
#ifdef BUILD_PCM_PLUGIN_ROUTE
snd_pcm_plug_change_channels,
#endif
#ifdef BUILD_PCM_PLUGIN_RATE
snd_pcm_plug_change_rate,
#endif
#ifdef BUILD_PCM_PLUGIN_ROUTE
snd_pcm_plug_change_channels,
#endif
snd_pcm_plug_change_format,
snd_pcm_plug_change_access
};
@ -551,7 +622,8 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
client->access != p.access) {
snd_pcm_t *new;
int err;
assert(k < sizeof(funcs)/sizeof(*funcs));
if (k >= sizeof(funcs)/sizeof(*funcs))
return -EINVAL;
err = funcs[k](pcm, &new, client, &p);
if (err < 0) {
snd_pcm_plug_clear(pcm);
@ -564,6 +636,7 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
}
k++;
}
#ifdef BUILD_PCM_PLUGIN_ROUTE
/* it's exception, user specified ttable, but no reduction/expand */
if (plug->ttable && !plug->ttable_ok) {
snd_pcm_t *new;
@ -580,6 +653,7 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
pcm->fast_ops = new->fast_ops;
pcm->fast_op_arg = new->fast_op_arg;
}
#endif
return 0;
}
@ -1079,6 +1153,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
slave = n;
continue;
}
#ifdef BUILD_PCM_PLUGIN_ROUTE
if (strcmp(id, "ttable") == 0) {
route_policy = PLUG_ROUTE_POLICY_NONE;
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
@ -1106,6 +1181,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
route_policy = PLUG_ROUTE_POLICY_DUP;
continue;
}
#endif
SNDERR("Unknown field %s", id);
return -EINVAL;
}
@ -1119,6 +1195,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
SND_PCM_HW_PARAM_RATE, SCONF_UNCHANGED, &srate);
if (err < 0)
return err;
#ifdef BUILD_PCM_PLUGIN_ROUTE
if (tt) {
err = snd_pcm_route_determine_ttable(tt, &csize, &ssize);
if (err < 0) {
@ -1136,6 +1213,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
return err;
}
}
#endif
err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
snd_config_delete(sconf);