]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Added route_policy option for the plug plugin.
authorJaroslav Kysela <perex@perex.cz>
Thu, 19 Jul 2001 09:11:05 +0000 (09:11 +0000)
committerJaroslav Kysela <perex@perex.cz>
Thu, 19 Jul 2001 09:11:05 +0000 (09:11 +0000)
Some fixes in the route and hooks plugin.

doc/asoundrc.doc
src/pcm/pcm_hooks.c
src/pcm/pcm_plug.c
src/pcm/pcm_route.c

index fa354fd8b0974a31d23f6de15f9b7cbf265361c9..dcae7c271cb35d8a1c67331a23d1f74b3cccb845 100644 (file)
@@ -128,6 +128,11 @@ pcm.NAME {
     [channels INT]     # Slave channels (default nearest) or "unchanged"
     [rate INT]         # Slave rate (default nearest) or "unchanged"
   }
+  route_policy STR     # route policy for automatic ttable generation
+                       # STR can be 'sum', 'copy', 'duplicate'
+                       # sum: result is sum of input channels
+                       # copy: only first channels are copied to destination
+                       # duplicate: duplicate first set of channels
   ttable {             # Transfer table (bidimensional compound of 
                        # cchannels * schannels numbers)
     CCHANNEL {
index 5d27a69e7b3439549b5853bb46efdbb7b53a10a4..49a59c1dd1c3ce0b560f8f9849bf722fa5358169 100644 (file)
@@ -319,7 +319,7 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
        return 0;
 }
 
-int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_t *conf)
+static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_t *conf)
 {
        int err;
        char buf[256];
index 023110ab92f906c9a90af838a100b0751cb3b85f..b3c397c106be38d7da945e8a5e9f90a529759c08 100644 (file)
 #include "pcm_local.h"
 #include "pcm_plugin.h"
 
+enum snd_pcm_plug_route_policy {
+       PLUG_ROUTE_POLICY_NONE,
+       PLUG_ROUTE_POLICY_COPY,
+       PLUG_ROUTE_POLICY_SUM,
+       PLUG_ROUTE_POLICY_DUP,
+};
+
 typedef struct {
        snd_pcm_t *req_slave;
        int close_slave;
@@ -29,6 +36,7 @@ typedef struct {
        snd_pcm_format_t sformat;
        int schannels;
        int srate;
+       enum snd_pcm_plug_route_policy route_policy;
        snd_pcm_route_ttable_entry_t *ttable;
        unsigned int tt_ssize, tt_cused, tt_sused;
 } snd_pcm_plug_t;
@@ -249,31 +257,50 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
                ttable = alloca(tt_cused * tt_sused * sizeof(*ttable));
                for (k = 0; k < tt_cused * tt_sused; ++k)
                        ttable[k] = 0;
-               if (clt->channels > slv->channels) {
-                       n = clt->channels;
-               } else {
-                       n = slv->channels;
-               }
-               while (n-- > 0) {
-                       snd_pcm_route_ttable_entry_t v = FULL;
-                       if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
-                           clt->channels > slv->channels) {
-                               int srcs = clt->channels / slv->channels;
-                               if (s < clt->channels % slv->channels)
-                                       srcs++;
-                               v /= srcs;
-                       } else if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
-                                  slv->channels > clt->channels) {
-                               int srcs = slv->channels / clt->channels;
-                               if (s < slv->channels % clt->channels)
-                                       srcs++;
-                               v /= srcs;
+               switch (plug->route_policy) {
+               case PLUG_ROUTE_POLICY_SUM:
+               case PLUG_ROUTE_POLICY_DUP:
+                       if (clt->channels > slv->channels) {
+                               n = clt->channels;
+                       } else {
+                               n = slv->channels;
+                       }
+                       while (n-- > 0) {
+                               snd_pcm_route_ttable_entry_t v = FULL;
+                               if (plug->route_policy == PLUG_ROUTE_POLICY_SUM) {
+                                       if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
+                                           clt->channels > slv->channels) {
+                                               int srcs = clt->channels / slv->channels;
+                                               if (s < clt->channels % slv->channels)
+                                                       srcs++;
+                                               v /= srcs;
+                                       } else if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
+                                                  slv->channels > clt->channels) {
+                                                       int srcs = slv->channels / clt->channels;
+                                               if (s < slv->channels % clt->channels)
+                                                       srcs++;
+                                               v /= srcs;
+                                       }
+                               }
+                               ttable[c * tt_ssize + s] = v;
+                               if (++c == clt->channels)
+                                       c = 0;
+                               if (++s == slv->channels)
+                                       s = 0;
                        }
-                       ttable[c * tt_ssize + s] = v;
-                       if (++c == clt->channels)
-                               c = 0;
-                       if (++s == slv->channels)
-                               s = 0;
+                       break;
+               case PLUG_ROUTE_POLICY_COPY:
+                       if (clt->channels < slv->channels) {
+                               n = clt->channels;
+                       } else {
+                               n = slv->channels;
+                       }
+                       for (c = 0; (int)c < n; c++)
+                               ttable[c * tt_ssize + c] = FULL;
+                       break;
+               default:
+                       SNDERR("Invalid route policy");
+                       break;
                }
        }
        err = snd_pcm_route_open(new, NULL, slv->format, (int) slv->channels, ttable, tt_ssize, tt_cused, tt_sused, plug->slave, plug->slave != plug->req_slave);
@@ -701,6 +728,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,
+                     enum snd_pcm_plug_route_policy route_policy,
                      snd_pcm_route_ttable_entry_t *ttable,
                      unsigned int tt_ssize,
                      unsigned int tt_cused, unsigned int tt_sused,
@@ -718,6 +746,7 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
        plug->srate = srate;
        plug->slave = plug->req_slave = slave;
        plug->close_slave = close_slave;
+       plug->route_policy = route_policy;
        plug->ttable = ttable;
        plug->tt_ssize = tt_ssize;
        plug->tt_cused = tt_cused;
@@ -751,6 +780,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
        snd_pcm_t *spcm;
        snd_config_t *slave = NULL, *sconf;
        snd_config_t *tt = NULL;
+       enum snd_pcm_plug_route_policy route_policy = PLUG_ROUTE_POLICY_SUM;
        snd_pcm_route_ttable_entry_t *ttable = NULL;
        unsigned int cused, sused;
        snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
@@ -765,6 +795,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                        continue;
                }
                if (strcmp(id, "ttable") == 0) {
+                       route_policy = PLUG_ROUTE_POLICY_NONE;
                        if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
                                SNDERR("Invalid type for %s", id);
                                return -EINVAL;
@@ -772,6 +803,19 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                        tt = n;
                        continue;
                }
+               if (strcmp(id, "route_policy") == 0) {
+                       const char *str;
+                       if ((err = snd_config_get_string(n, &str)) < 0) {
+                               SNDERR("Invalid type for %s", id);
+                               return -EINVAL;
+                       }
+                       if (!strcmp(str, "sum"))
+                               route_policy = PLUG_ROUTE_POLICY_SUM;
+                       else if (!strcmp(str, "copy"))
+                               route_policy = PLUG_ROUTE_POLICY_COPY;
+                       else if (!strcmp(str, "duplicate"))
+                               route_policy = PLUG_ROUTE_POLICY_DUP;
+               }
                SNDERR("Unknown field %s", id);
                return -EINVAL;
        }
@@ -800,7 +844,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
        if (err < 0)
                return err;
        err = snd_pcm_plug_open(pcmp, name, sformat, schannels, srate,
-                               ttable, MAX_CHANNELS, cused, sused, spcm, 1);
+                               route_policy, ttable, MAX_CHANNELS, cused, sused, spcm, 1);
        if (err < 0)
                snd_pcm_close(spcm);
        return err;
index 1d400c3324c35d7cf7cc7fbad7408dba0bece61c..204593b40c42d38816f19912332cf0fe55bdfc87 100644 (file)
@@ -617,7 +617,11 @@ static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)
                while (1) {
                        snd_pcm_route_ttable_src_t *s = &d->srcs[src];
                        if (d->att)
+#if ROUTE_PLUGIN_FLOAT
                                snd_output_printf(out, "%d*%g", s->channel, s->as_float);
+#else
+                               snd_output_printf(out, "%d*%g", s->channel, (double)s->as_int / (double)ROUTE_PLUGIN_RESOLUTION);
+#endif
                        else
                                snd_output_printf(out, "%d", s->channel);
                        src++;
@@ -768,10 +772,10 @@ int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
        return 0;
 }
 
-int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable,
-                             unsigned int tt_csize, unsigned int tt_ssize,
-                             unsigned int *tt_cused, unsigned int *tt_sused,
-                             int schannels)
+static int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable,
+                                    unsigned int tt_csize, unsigned int tt_ssize,
+                                    unsigned int *tt_cused, unsigned int *tt_sused,
+                                    int schannels)
 {
        int cused = -1;
        int sused = -1;