- route_t *data = (route_t *)plugin->extra_data;
- int schannels = plugin->src_format.channels;
- int dchannels = plugin->dst_format.channels;
- bitset_t *vmask = plugin->src_vmask;
- int channel;
- ttable_dst_t *dp = data->ttable;
- bitset_zero(vmask, schannels);
- for (channel = 0; channel < dchannels; channel++, dp++) {
- unsigned int src;
- ttable_src_t *sp;
- if (!bitset_get(dst_vmask, channel))
- continue;
- sp = dp->srcs;
- for (src = 0; src < dp->nsrcs; src++, sp++)
- bitset_set(vmask, sp->channel);
- }
- *src_vmask = vmask;
- return 0;
-}
-
-int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
- bitset_t *src_vmask,
- bitset_t **dst_vmask)
-{
- route_t *data = (route_t *)plugin->extra_data;
- int dchannels = plugin->dst_format.channels;
- bitset_t *vmask = plugin->dst_vmask;
- int channel;
- ttable_dst_t *dp = data->ttable;
- bitset_zero(vmask, dchannels);
- for (channel = 0; channel < dchannels; channel++, dp++) {
- unsigned int src;
- ttable_src_t *sp;
- sp = dp->srcs;
- for (src = 0; src < dp->nsrcs; src++, sp++) {
- if (bitset_get(src_vmask, sp->channel)) {
- bitset_set(vmask, channel);
- break;
- }
- }
- }
- *dst_vmask = vmask;
- return 0;
-}
-
-static void route_free(snd_pcm_plugin_t *plugin)
-{
- route_t *data = (route_t *)plugin->extra_data;
- unsigned int dst_channel;
- for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
- if (data->ttable[dst_channel].srcs != NULL)
- kfree(data->ttable[dst_channel].srcs);
- }
-}
-
-static int route_load_ttable(snd_pcm_plugin_t *plugin,
- const route_ttable_entry_t* src_ttable)
-{
- route_t *data;
- unsigned int src_channel, dst_channel;
- const route_ttable_entry_t *sptr;
- ttable_dst_t *dptr;
- if (src_ttable == NULL)
- return 0;
- data = (route_t *)plugin->extra_data;
- dptr = data->ttable;
- sptr = src_ttable;
- plugin->private_free = route_free;
- for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
- route_ttable_entry_t t = 0;
- int att = 0;
- int nsrcs = 0;
- ttable_src_t srcs[plugin->src_format.channels];
- for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
- snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO);
- if (*sptr != 0) {
- srcs[nsrcs].channel = src_channel;
-#if ROUTE_PLUGIN_USE_FLOAT
- /* Also in user space for non attenuated */
- srcs[nsrcs].as_int = (*sptr == FULL ? ROUTE_PLUGIN_RESOLUTION : 0);
- srcs[nsrcs].as_float = *sptr;
-#else
- srcs[nsrcs].as_int = *sptr;
-#endif
- if (*sptr != FULL)
- att = 1;
- t += *sptr;
- nsrcs++;
- }
- sptr++;
- }
- dptr->att = att;
- dptr->nsrcs = nsrcs;
- if (nsrcs == 0)
- dptr->func = route_to_channel_from_zero;
- else if (nsrcs == 1 && !att)
- dptr->func = route_to_channel_from_one;
- else
- dptr->func = route_to_channel;
- if (nsrcs > 0) {
- int srcidx;
- dptr->srcs = snd_kcalloc(nsrcs * sizeof(*srcs), GFP_KERNEL);
- for(srcidx = 0; srcidx < nsrcs; srcidx++)
- dptr->srcs[srcidx] = srcs[srcidx];
- } else
- dptr->srcs = 0;
- dptr++;
- }
- return 0;
-}
-
-static snd_pcm_sframes_t route_transfer(snd_pcm_plugin_t *plugin,
- const snd_pcm_plugin_channel_t *src_channels,
- snd_pcm_plugin_channel_t *dst_channels,
- snd_pcm_uframes_t frames)
-{
- route_t *data;
- int src_nchannels, dst_nchannels;
- int dst_channel;
- ttable_dst_t *ttp;
- snd_pcm_plugin_channel_t *dvp;