]> git.alsa-project.org Git - alsa-plugins.git/commitdiff
aaf: Load configuration parameters
authorAndre Guedes <andre.guedes@intel.com>
Thu, 25 Oct 2018 01:11:11 +0000 (18:11 -0700)
committerJaroslav Kysela <perex@perex.cz>
Thu, 25 Oct 2018 06:09:02 +0000 (08:09 +0200)
This patch implements the infrastructure to load the plugin
configuration from ALSA configuration file. The configuration
is loaded in open() callback.

All configuration parameters are described in details in doc/aaf.txt
file.

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
aaf/pcm_aaf.c
configure.ac
doc/aaf.txt

index 31d8759bf8773848f2a3ff0bb2097ce24443f6a8..c9d4b70ece80685a55a61b4a1b997220c8c5f1ba 100644 (file)
 
 #include <alsa/asoundlib.h>
 #include <alsa/pcm_external.h>
+#include <linux/if_ether.h>
+#include <net/if.h>
+#include <string.h>
+#include <stdint.h>
+
+#define NSEC_PER_USEC 1000
 
 typedef struct {
        snd_pcm_ioplug_t io;
+
+       char ifname[IFNAMSIZ];
+       unsigned char addr[ETH_ALEN];
+       int prio;
+       uint64_t streamid;
+       int mtt;
+       int t_uncertainty;
+       snd_pcm_uframes_t frames_per_pdu;
 } snd_pcm_aaf_t;
 
+static int aaf_load_config(snd_pcm_aaf_t *aaf, snd_config_t *conf)
+{
+       snd_config_iterator_t cur, next;
+
+       snd_config_for_each(cur, next, conf) {
+               snd_config_t *entry = snd_config_iterator_entry(cur);
+               const char *id;
+
+               if (snd_config_get_id(entry, &id) < 0)
+                       goto err;
+
+               if (strcmp(id, "comment") == 0 ||
+                   strcmp(id, "type") == 0 ||
+                   strcmp(id, "hint") == 0)
+                       continue;
+
+               if (strcmp(id, "ifname") == 0) {
+                       const char *ifname;
+
+                       if (snd_config_get_string(entry, &ifname) < 0)
+                               goto err;
+
+                       snprintf(aaf->ifname, sizeof(aaf->ifname), "%s",
+                                ifname);
+               } else if (strcmp(id, "addr") == 0) {
+                       const char *addr;
+                       int n;
+
+                       if (snd_config_get_string(entry, &addr) < 0)
+                               goto err;
+
+                       n = sscanf(addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+                                  &aaf->addr[0], &aaf->addr[1],
+                                  &aaf->addr[2], &aaf->addr[3],
+                                  &aaf->addr[4], &aaf->addr[5]);
+                       if (n != 6)
+                               goto err;
+               } else if (strcmp(id, "prio") == 0) {
+                       long prio;
+
+                       if (snd_config_get_integer(entry, &prio) < 0)
+                               goto err;
+
+                       if (prio < 0)
+                               goto err;
+
+                       aaf->prio = prio;
+               } else if (strcmp(id, "streamid") == 0) {
+                       const char *streamid;
+                       unsigned char addr[6];
+                       unsigned short unique_id;
+                       int n;
+
+                       if (snd_config_get_string(entry, &streamid) < 0)
+                               goto err;
+
+                       n = sscanf(streamid,
+                                  "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hx",
+                                  &addr[0], &addr[1], &addr[2], &addr[3],
+                                  &addr[4], &addr[5], &unique_id);
+                       if (n != 7)
+                               goto err;
+
+                       aaf->streamid = (uint64_t) addr[0] << 56 |
+                                       (uint64_t) addr[1] << 48 |
+                                       (uint64_t) addr[2] << 40 |
+                                       (uint64_t) addr[3] << 32 |
+                                       (uint64_t) addr[4] << 24 |
+                                       (uint64_t) addr[5] << 16 |
+                                       unique_id;
+               } else if (strcmp(id, "mtt") == 0) {
+                       long mtt;
+
+                       if (snd_config_get_integer(entry, &mtt) < 0)
+                               goto err;
+
+                       if (mtt < 0)
+                               goto err;
+
+                       aaf->mtt = mtt * NSEC_PER_USEC;
+               } else if (strcmp(id, "time_uncertainty") == 0) {
+                       long t_uncertainty;
+
+                       if (snd_config_get_integer(entry, &t_uncertainty) < 0)
+                               goto err;
+
+                       if (t_uncertainty < 0)
+                               goto err;
+
+                       aaf->t_uncertainty = t_uncertainty * NSEC_PER_USEC;
+               } else if (strcmp(id, "frames_per_pdu") == 0) {
+                       long frames_per_pdu;
+
+                       if (snd_config_get_integer(entry, &frames_per_pdu) < 0)
+                               goto err;
+
+                       if (frames_per_pdu < 0)
+                               goto err;
+
+                       aaf->frames_per_pdu = frames_per_pdu;
+               } else {
+                       SNDERR("Invalid configuration: %s", id);
+                       goto err;
+               }
+       }
+
+       return 0;
+
+err:
+       SNDERR("Error loading device configuration");
+       return -EINVAL;
+}
+
 static int aaf_close(snd_pcm_ioplug_t *io)
 {
        free(io->private_data);
@@ -64,6 +191,10 @@ SND_PCM_PLUGIN_DEFINE_FUNC(aaf)
                return -ENOMEM;
        }
 
+       res = aaf_load_config(aaf, conf);
+       if (res < 0)
+               goto err;
+
        aaf->io.version = SND_PCM_IOPLUG_VERSION;
        aaf->io.name = "AVTP Audio Format (AAF) Plugin";
        aaf->io.callback = &aaf_callback;
index db36f0316b3f8ed4fc7d98d07a94b906fd912141..eadaed62bc08a74ee7d7836ff64f487cc907070d 100644 (file)
@@ -181,6 +181,7 @@ AC_ARG_ENABLE([aaf],
 
 if test "x$enable_aaf" != "xno"; then
   PKG_CHECK_MODULES(AVTP, avtp >= 0.1, [HAVE_AAF=yes], [HAVE_AAF=no])
+  AC_CHECK_HEADERS([linux/if_ether.h], [], [HAVE_AAF=no])
 fi
 AM_CONDITIONAL(HAVE_AAF, test x$HAVE_AAF = xyes)
 
index b260a26cf962e6d8eb190c1e1f86b4e17a48843e..afc794b3052149f3c631fe58ff4b0a5ae53c8956 100644 (file)
@@ -14,5 +14,36 @@ Plugin Dependencies
 
 The AAF plugin uses libavtp to handle AVTP packetization. Libavtp source code
 can be found in https://github.com/AVnu/libavtp as well as instructions to
-build and install it. If libavtp isn't detected by configure, the plugin isn't
+build and install it.
+
+The plugin also depends on some kernel API headers such as linux/if_ether.h so
+make sure you have them installed in your system.
+
+If libavtp or the kernel headers aren't detected by configure, the plugin isn't
 built.
+
+Plugin Configuration
+--------------------
+
+The plugin parameters are passed via ALSA configuration file. They are defined
+as follows:
+
+       * ifname: Network interface used to transmit/receive AVTP packets.
+
+       * addr: Stream destination MAC address.
+
+       * prio: Priority used by the plugin to transmit AVTP traffic. This
+         option is relevant only when operating in playback mode.
+
+       * streamid: Stream ID associated with the AAF stream transmitted or
+         received by the plugin.
+
+       * mtt: Maximum Transit Time (in microseconds) as defined in AVTP spec
+         section 4.3.3. This option is relevant only when operating in
+         playback mode.
+
+       * time_uncertainty: Maximum Time Uncertainty (in microseconds) as
+         defined by AVTP spec section 4.3.3. This option is relevant only when
+         operating in playback mode.
+
+       * frames_per_pdu: Number of audio frames transmitted in one AVTPDU.