audiod: Allow regular expressions in receiver config.
authorAndre Noll <maan@systemlinux.org>
Tue, 19 Apr 2011 16:18:45 +0000 (18:18 +0200)
committerAndre Noll <maan@systemlinux.org>
Fri, 3 Jun 2011 06:39:20 +0000 (08:39 +0200)
The audio format substring of the reciever arg can now be a regular
expression rather than only the name of an audio format. This way
one can easily choose the same receiver for all audio formats by
saying e.g.

receiver ".:udp"

This works because the regex "." matches all audio formats.

audiod.c

index 6a4c9db..1f1f1aa 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -178,6 +178,22 @@ static int get_audio_format_num(const char *name)
        return -E_UNSUPPORTED_AUDIO_FORMAT;
 }
 
        return -E_UNSUPPORTED_AUDIO_FORMAT;
 }
 
+static int get_matching_audio_format_nums(const char *re)
+{
+       int i, ret;
+       regex_t preg;
+
+       ret = para_regcomp(&preg, re, REG_EXTENDED | REG_NOSUB);
+       if (ret < 0)
+               return ret;
+       ret = 0;
+       FOR_EACH_AUDIO_FORMAT(i)
+               if (regexec(&preg, audio_formats[i], 0, NULL, 0) != REG_NOMATCH)
+                       ret |= (1 << i);
+       regfree(&preg);
+       return ret;
+}
+
 /**
  * Compute the play time based on information of the given slot.
  *
 /**
  * Compute the play time based on information of the given slot.
  *
@@ -793,28 +809,35 @@ static int parse_receiver_args(void)
        for (i = conf.receiver_given - 1; i >= 0; i--) {
                char *arg = conf.receiver_arg[i];
                char *recv_arg = strchr(arg, ':');
        for (i = conf.receiver_given - 1; i >= 0; i--) {
                char *arg = conf.receiver_arg[i];
                char *recv_arg = strchr(arg, ':');
+               int af_mask, j;
+
                ret = -E_MISSING_COLON;
                if (!recv_arg)
                        goto out;
                *recv_arg = '\0';
                recv_arg++;
                ret = -E_MISSING_COLON;
                if (!recv_arg)
                        goto out;
                *recv_arg = '\0';
                recv_arg++;
-               ret = get_audio_format_num(arg);
+               ret = get_matching_audio_format_nums(arg);
                if (ret < 0)
                        goto out;
                if (ret < 0)
                        goto out;
-               /*
-                * If multiple receivers are given for this audio format, the
-                * last one wins and we have to free the previous receiver
-                * config here. Since we are iterating backwards, the winning
-                * receiver arg is in fact the first one given.
-                */
-               if (afi[ret].receiver_conf)
-                       afi[ret].receiver->free_config(afi[ret].receiver_conf);
-               afi[ret].receiver_conf = check_receiver_arg(recv_arg, &receiver_num);
-               if (!afi[ret].receiver_conf) {
+               af_mask = ret;
+               FOR_EACH_AUDIO_FORMAT(j) {
+                       a = afi + j;
+                       if ((af_mask & (1 << j)) == 0) /* no match */
+                               continue;
+                       /*
+                        * If multiple receivers are given for this audio format, the
+                        * last one wins and we have to free the previous receiver
+                        * config here. Since we are iterating backwards, the winning
+                        * receiver arg is in fact the first one given.
+                        */
+                       if (a->receiver_conf)
+                               a->receiver->free_config(a->receiver_conf);
+                       a->receiver_conf = check_receiver_arg(recv_arg, &receiver_num);
                        ret = -E_RECV_SYNTAX;
                        ret = -E_RECV_SYNTAX;
-                       goto out;
+                       if (!a->receiver_conf)
+                               goto out;
+                       a->receiver = receivers + receiver_num;
                }
                }
-               afi[ret].receiver = &receivers[receiver_num];
        }
        /*
         * Use the first available receiver with no arguments for those audio
        }
        /*
         * Use the first available receiver with no arguments for those audio
@@ -830,6 +853,11 @@ static int parse_receiver_args(void)
                        return -E_RECV_SYNTAX;
                a->receiver = &receivers[receiver_num];
        }
                        return -E_RECV_SYNTAX;
                a->receiver = &receivers[receiver_num];
        }
+       FOR_EACH_AUDIO_FORMAT(i) {
+               a = afi + i;
+               PARA_INFO_LOG("receiving %s streams via %s receiver\n",
+                       audio_formats[i], a->receiver->name);
+       }
        ret = 1;
 out:
        free(cmd);
        ret = 1;
 out:
        free(cmd);