OSDN Git Service

Added hooked PCM type (one sample hook implementation will follow). Some cleaning.
authorAbramo Bagnara <abramo@alsa-project.org>
Mon, 4 Jun 2001 18:04:18 +0000 (18:04 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Mon, 4 Jun 2001 18:04:18 +0000 (18:04 +0000)
28 files changed:
doc/asoundrc.doc
include/local.h
include/pcm.h
src/control/control.c
src/pcm/Makefile.am
src/pcm/pcm.c
src/pcm/pcm_adpcm.c
src/pcm/pcm_alaw.c
src/pcm/pcm_copy.c
src/pcm/pcm_file.c
src/pcm/pcm_hooks.c [new file with mode: 0644]
src/pcm/pcm_hw.c
src/pcm/pcm_linear.c
src/pcm/pcm_local.h
src/pcm/pcm_meter.c
src/pcm/pcm_meter.h [deleted file]
src/pcm/pcm_mulaw.c
src/pcm/pcm_multi.c
src/pcm/pcm_null.c
src/pcm/pcm_params.c
src/pcm/pcm_plug.c
src/pcm/pcm_rate.c
src/pcm/pcm_route.c
src/pcm/pcm_share.c
src/pcm/pcm_shm.c
src/pcm/pcm_surr.c
src/rawmidi/rawmidi.c
src/seq/seq.c

index 143a9af..e2f8c29 100644 (file)
@@ -18,6 +18,12 @@ pcm_scope_type.NAME {
   [open STR]           # Open function (default _snd_pcm_scope_NAME_open)
 }
 
+# PCM scope definition
+pcm_scope.NAME {
+  type STR             # Scope type
+  ...
+}
+
 # Slave PCM definition
 pcm_slave.NAME {
   pcm STR              # PCM name
@@ -31,11 +37,26 @@ pcm_slave.NAME {
   etc.
 }
 
+# Hook arguments definition
+hook_args.NAME {
+  ...                  # Arbitrary arguments
+}
+
+# PCM hook definition
+pcm_hook.NAME {
+  [lib STR]            # Library file (default libasound.so)
+  [install STR]                # Install function (default _snd_pcm_hook_NAME_install)
+  [args STR]           # Arguments for install function (see hook_args)
+  # or
+  [args { }]           # Arguments for install function
+}
+
 # PCM definition
 pcm.NAME {
   type STR             # Type
   [comment ANY]                # Saved comments
 
+
 # PCM types:
   type hw              # Kernel PCM
   card INT/STR         # Card name or number
@@ -43,10 +64,24 @@ pcm.NAME {
   [subdevice] INT      # Subdevice number, -1 first available (default -1)
 
 
+  type hooks           # PCM with hooks
+  slave STR            # Slave name (see pcm_slave)
+  # or
+  slave {              # Slave definition
+    pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
+  }
+  hooks {
+    ID STR             # Hook name (see pcm_hook)
+    # or
+    ID { }             # Hook definition (see pcm_hook)
+  }
+
   type plug            # Format adjusted PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -59,13 +94,23 @@ pcm.NAME {
   }
 
 
+  type copy            # Copy conversion PCM
+  slave STR            # Slave name (see pcm_slave)
+  # or
+  slave {              # Slave definition
+    pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
+  }
+
+
   type linear          # Linear format conversion PCM
   type adpcm           # IMA-ADPCM format conversion PCM
   type alaw            # A-Law format conversion PCM
   type mulaw           # Mu-Law format conversion PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -74,9 +119,9 @@ pcm.NAME {
 
 
   type rate            # Rate conversion PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -86,9 +131,9 @@ pcm.NAME {
 
 
   type route           # Attenuated static route PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -105,9 +150,9 @@ pcm.NAME {
 
   type multi           # Linked PCMs (exclusive access to selected channels)
   slaves {             # Slaves definitions
-    N STR              # Slave name for slave N
+    ID STR             # Slave name for slave N (see pcm_slave)
     # or
-    N {                        # Slave definition for slave N
+    ID {               # Slave definition for slave N
       pcm STR          # Slave PCM name
     # or
       pcm { }          # Slave PCM definition
@@ -123,9 +168,9 @@ pcm.NAME {
 
 
   type file            # File plugin
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -137,7 +182,7 @@ pcm.NAME {
 
 
   type meter           # Meter PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
@@ -146,17 +191,16 @@ pcm.NAME {
   }
   [frequency INT]      # Updates per second
   scopes {             # Scopes
-    N {                        # Scope definition
-      type STR         # Scope type
-      [PARAMS]         # Scope params
-    }
+    ID STR             # Scope name (see pcm_scope)
+  # or
+    ID { }             # Scope definition (see pcm_scope)
   }
 
 
   type droute          # Attenuated dynamic route PCM (NYI)
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -165,7 +209,7 @@ pcm.NAME {
   }
   ctl STR              # Ctl name
   bindings {           # Bindings table
-    N {                        # Binding entry
+    ID {               # Binding entry
       cchannels {      # Client channels
         C INT          # Client channel
       }
@@ -179,9 +223,9 @@ pcm.NAME {
 
   type loopback                # Loopback server (NYI)
   server STR           # Server name
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   # or
-  slave {              # Slave definition or name
+  slave {              # Slave definition
     pcm STR            # Slave PCM name
     # or
     pcm { }            # Slave PCM definition
@@ -198,14 +242,14 @@ pcm.NAME {
 
 
   type share           # Share PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   bindings {           # Bindings table
     N INT              # Slave channel for client channel N
   }
 
 
   type mix             # Mix PCM
-  slave STR            # Slave name
+  slave STR            # Slave name (see pcm_slave)
   bindings {           # Bindings table
     N INT              # Slave channel for client channel N
   }
@@ -317,19 +361,7 @@ pcm.m {
        }
 }
 
-scope_type.level {
+pcm_scope_type.level {
        lib /home/abramo/scopes/liblevel.so
 } 
 
-Special PCM names:
-hw:CARD,DEV,SUBDEV
-hw:CARD,DEV
-plug:CARD,DEV,SUBDEV
-plug:CARD,DEV
-plug:SLAVE_PCM
-shm:SOCKET,PCM
-file:FNAME,FMT,SLAVE_PCM
-file:FNAME,FMT
-file:FNAME
-null
-
index 3bf29f9..ceb613d 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef __LOCAL_H
 #define __LOCAL_H
 
+#define ALSA_LIB "libasound.so"
+
 #ifndef DATADIR
 #define DATADIR "/usr/share"
 #endif
index 47a5fa7..2f537f2 100644 (file)
@@ -235,6 +235,8 @@ typedef struct _snd_pcm snd_pcm_t;
 enum _snd_pcm_type {
        /** Kernel level PCM */
        SND_PCM_TYPE_HW,
+       /** Hooked PCM */
+       SND_PCM_TYPE_HOOKS,
        /** One ore more linked PCM with exclusive access to selected
            channels */
        SND_PCM_TYPE_MULTI,
@@ -718,6 +720,22 @@ void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val);
 void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val);
 void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val);
 
+typedef enum _snd_pcm_hook_type {
+       SND_PCM_HOOK_HW_PARAMS,
+       SND_PCM_HOOK_HW_FREE,
+       SND_PCM_HOOK_CLOSE,
+       SND_PCM_HOOK_LAST = SND_PCM_HOOK_CLOSE,
+} snd_pcm_hook_type_t;
+
+typedef struct _snd_pcm_hook snd_pcm_hook_t;
+typedef int (*snd_pcm_hook_func_t)(snd_pcm_hook_t *hook);
+snd_pcm_t *snd_pcm_hook_get_pcm(snd_pcm_hook_t *hook);
+void *snd_pcm_hook_get_private(snd_pcm_hook_t *hook);
+int snd_pcm_hook_add(snd_pcm_hook_t **hookp, snd_pcm_t *pcm,
+                    snd_pcm_hook_type_t type,
+                    snd_pcm_hook_func_t func, void *private_data);
+int snd_pcm_hook_remove(snd_pcm_hook_t *hook);
+
 #ifdef __cplusplus
 }
 #endif
index 937ae28..9048276 100644 (file)
@@ -444,7 +444,7 @@ int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
                snprintf(buf, sizeof(buf), "_snd_ctl_%s_open", str);
        }
        if (!lib)
-               lib = "libasound.so";
+               lib = ALSA_LIB;
        h = dlopen(lib, RTLD_NOW);
        if (!h) {
                SNDERR("Cannot open shared library %s", lib);
index b257aaf..cec1f31 100644 (file)
@@ -2,11 +2,12 @@
 EXTRA_LTLIBRARIES = libpcm.la
 
 libpcm_la_SOURCES = atomic.c mask.c interval.c \
-                   pcm.c pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
+                   pcm.c pcm_params.c \
+                   pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
                    pcm_route.c pcm_mulaw.c pcm_alaw.c pcm_adpcm.c \
                    pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
                    pcm_shm.c pcm_file.c pcm_null.c pcm_share.c \
-                   pcm_meter.c pcm_params.c pcm_surr.c
+                   pcm_meter.c pcm_hooks.c pcm_surr.c
 noinst_HEADERS = atomic.h pcm_local.h pcm_plugin.h mask.h mask_inline.h \
                 interval.h interval_inline.h plugin_ops.h
 
index 6095bd6..44050d9 100644 (file)
@@ -96,7 +96,6 @@ snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm)
  */
 int snd_pcm_close(snd_pcm_t *pcm)
 {
-       int ret = 0;
        int err;
        assert(pcm);
        if (pcm->setup) {
@@ -107,11 +106,11 @@ int snd_pcm_close(snd_pcm_t *pcm)
                        snd_pcm_drain(pcm);
                err = snd_pcm_hw_free(pcm);
                if (err < 0)
-                       ret = err;
+                       return err;
        }
-       if ((err = pcm->ops->close(pcm->op_arg)) < 0)
-               ret = err;
-       pcm->setup = 0;
+       err = pcm->ops->close(pcm->op_arg);
+       if (err < 0)
+               return err;
        if (pcm->name)
                free(pcm->name);
        free(pcm);
@@ -190,8 +189,9 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        int err;
        assert(pcm && params);
        err = _snd_pcm_hw_params(pcm, params);
-       if (err >= 0)
-               err = snd_pcm_prepare(pcm);
+       if (err < 0)
+               return err;
+       err = snd_pcm_prepare(pcm);
        return err;
 }
 
@@ -211,7 +211,9 @@ int snd_pcm_hw_free(snd_pcm_t *pcm)
        }
        err = pcm->ops->hw_free(pcm->op_arg);
        pcm->setup = 0;
-       return err;
+       if (err < 0)
+               return err;
+       return 0;
 }
 
 /** \brief Install PCM software configuration defined by params
@@ -975,7 +977,7 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
                snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
        }
        if (!lib)
-               lib = "libasound.so";
+               lib = ALSA_LIB;
        h = dlopen(lib, RTLD_NOW);
        if (!h) {
                SNDERR("Cannot open shared library %s", lib);
@@ -987,7 +989,10 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
                dlclose(h);
                return -ENXIO;
        }
-       return open_func(pcmp, name, pcm_conf, stream, mode);
+       err = open_func(pcmp, name, pcm_conf, stream, mode);
+       if (err < 0)
+               return err;
+       return 0;
 }
 
 static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, const char *name, 
@@ -4283,6 +4288,10 @@ int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf,
                        return err;
                }
        }
+       if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
+               SNDERR("Invalid slave definition");
+               return -EINVAL;
+       }
        va_start(args, count);
        for (k = 0; k < count; ++k) {
                fields[k].index = va_arg(args, int);
@@ -4354,4 +4363,16 @@ int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf,
        return 0;
 }
                
+
+int snd_pcm_conf_generic_id(const char *id)
+{
+       static const char *ids[] = { "comment", "type" };
+       unsigned int k;
+       for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) {
+               if (strcmp(id, ids[k]) == 0)
+                       return 1;
+       }
+       return 0;
+}
+
 #endif
index 69e2509..405e4d4 100644 (file)
@@ -559,9 +559,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index e2d57cf..71e0d2f 100644 (file)
@@ -432,9 +432,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index a9f85b8..a4bbd25 100644 (file)
@@ -201,9 +201,7 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index 9e378e0..d49c2a1 100644 (file)
@@ -466,9 +466,7 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
diff --git a/src/pcm/pcm_hooks.c b/src/pcm/pcm_hooks.c
new file mode 100644 (file)
index 0000000..0fd1965
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ *  PCM - Hook functions
+ *  Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2 of
+ *   the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Library General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+  
+#include <dlfcn.h>
+#include "pcm_local.h"
+
+#ifndef DOC_HIDDEN
+struct _snd_pcm_hook {
+       snd_pcm_t *pcm;
+       snd_pcm_hook_func_t func;
+       void *private_data;
+       struct list_head list;
+};
+
+typedef struct {
+       snd_pcm_t *slave;
+       int close_slave;
+       struct list_head hooks[SND_PCM_HOOK_LAST + 1];
+} snd_pcm_hooks_t;
+
+static int snd_pcm_hooks_close(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       struct list_head *pos, *next;
+       unsigned int k;
+       int err;
+       if (h->close_slave) {
+               err = snd_pcm_close(h->slave);
+               if (err < 0)
+                       return err;
+       }
+       list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_CLOSE]) {
+               snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
+               err = hook->func(hook);
+               if (err < 0)
+                       return err;
+       }
+       for (k = 0; k <= SND_PCM_HOOK_LAST; ++k) {
+               struct list_head *hooks = &h->hooks[k];
+               while (!list_empty(hooks)) {
+                       snd_pcm_hook_t *hook;
+                       pos = hooks->next;
+                       hook = list_entry(pos, snd_pcm_hook_t, list);
+                       snd_pcm_hook_remove(hook);
+               }
+       }
+       free(h);
+       return 0;
+}
+
+static int snd_pcm_hooks_nonblock(snd_pcm_t *pcm, int nonblock)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_nonblock(h->slave, nonblock);
+}
+
+static int snd_pcm_hooks_async(snd_pcm_t *pcm, int sig, pid_t pid)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_async(h->slave, sig, pid);
+}
+
+static int snd_pcm_hooks_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_info(h->slave, info);
+}
+
+static int snd_pcm_hooks_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_channel_info(h->slave, info);
+}
+
+static int snd_pcm_hooks_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_status(h->slave, status);
+}
+
+static snd_pcm_state_t snd_pcm_hooks_state(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_state(h->slave);
+}
+
+static int snd_pcm_hooks_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_delay(h->slave, delayp);
+}
+
+static int snd_pcm_hooks_prepare(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_prepare(h->slave);
+}
+
+static int snd_pcm_hooks_reset(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_reset(h->slave);
+}
+
+static int snd_pcm_hooks_start(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_start(h->slave);
+}
+
+static int snd_pcm_hooks_drop(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_drop(h->slave);
+}
+
+static int snd_pcm_hooks_drain(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_drain(h->slave);
+}
+
+static int snd_pcm_hooks_pause(snd_pcm_t *pcm, int enable)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_pause(h->slave, enable);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_rewind(h->slave, frames);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_writei(h->slave, buffer, size);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_writen(h->slave, bufs, size);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_readi(h->slave, buffer, size);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_readn(h->slave, bufs, size);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_mmap_commit(snd_pcm_t *pcm,
+                                                  snd_pcm_uframes_t offset,
+                                                  snd_pcm_uframes_t size)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_mmap_commit(h->slave, offset, size);
+}
+
+static snd_pcm_sframes_t snd_pcm_hooks_avail_update(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_avail_update(h->slave);
+}
+
+static int snd_pcm_hooks_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_hw_refine(h->slave, params);
+}
+
+static int snd_pcm_hooks_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       struct list_head *pos, *next;
+       int err = snd_pcm_hw_params(h->slave, params);
+       if (err < 0)
+               return err;
+       list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_HW_PARAMS]) {
+               snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
+               err = hook->func(hook);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+static int snd_pcm_hooks_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       struct list_head *pos, *next;
+       int err = snd_pcm_hw_free(h->slave);
+       if (err < 0)
+               return err;
+       list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_HW_FREE]) {
+               snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
+               err = hook->func(hook);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+static int snd_pcm_hooks_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_sw_params(h->slave, params);
+}
+
+static int snd_pcm_hooks_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       return 0;
+}
+
+static int snd_pcm_hooks_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       return 0;
+}
+
+static void snd_pcm_hooks_dump(snd_pcm_t *pcm, snd_output_t *out)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       snd_output_printf(out, "Hooks PCM\n");
+       if (pcm->setup) {
+               snd_output_printf(out, "Its setup is:\n");
+               snd_pcm_dump_setup(pcm, out);
+       }
+       snd_output_printf(out, "Slave: ");
+       snd_pcm_dump(h->slave, out);
+}
+
+snd_pcm_ops_t snd_pcm_hooks_ops = {
+       close: snd_pcm_hooks_close,
+       info: snd_pcm_hooks_info,
+       hw_refine: snd_pcm_hooks_hw_refine,
+       hw_params: snd_pcm_hooks_hw_params,
+       hw_free: snd_pcm_hooks_hw_free,
+       sw_params: snd_pcm_hooks_sw_params,
+       channel_info: snd_pcm_hooks_channel_info,
+       dump: snd_pcm_hooks_dump,
+       nonblock: snd_pcm_hooks_nonblock,
+       async: snd_pcm_hooks_async,
+       mmap: snd_pcm_hooks_mmap,
+       munmap: snd_pcm_hooks_munmap,
+};
+
+snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
+       status: snd_pcm_hooks_status,
+       state: snd_pcm_hooks_state,
+       delay: snd_pcm_hooks_delay,
+       prepare: snd_pcm_hooks_prepare,
+       reset: snd_pcm_hooks_reset,
+       start: snd_pcm_hooks_start,
+       drop: snd_pcm_hooks_drop,
+       drain: snd_pcm_hooks_drain,
+       pause: snd_pcm_hooks_pause,
+       rewind: snd_pcm_hooks_rewind,
+       writei: snd_pcm_hooks_writei,
+       writen: snd_pcm_hooks_writen,
+       readi: snd_pcm_hooks_readi,
+       readn: snd_pcm_hooks_readn,
+       avail_update: snd_pcm_hooks_avail_update,
+       mmap_commit: snd_pcm_hooks_mmap_commit,
+};
+
+int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int close_slave)
+{
+       snd_pcm_t *pcm;
+       snd_pcm_hooks_t *h;
+       unsigned int k;
+       assert(pcmp && slave);
+       h = calloc(1, sizeof(snd_pcm_hooks_t));
+       if (!h)
+               return -ENOMEM;
+       h->slave = slave;
+       h->close_slave = close_slave;
+       for (k = 0; k <= SND_PCM_HOOK_LAST; ++k) {
+               INIT_LIST_HEAD(&h->hooks[k]);
+       }
+       pcm = calloc(1, sizeof(snd_pcm_t));
+       if (!pcm) {
+               free(h);
+               return -ENOMEM;
+       }
+       if (name)
+               pcm->name = strdup(name);
+       pcm->type = SND_PCM_TYPE_HOOKS;
+       pcm->stream = slave->stream;
+       pcm->mode = slave->mode;
+       pcm->ops = &snd_pcm_hooks_ops;
+       pcm->op_arg = pcm;
+       pcm->fast_ops = &snd_pcm_hooks_fast_ops;
+       pcm->fast_op_arg = pcm;
+       pcm->private_data = h;
+       pcm->poll_fd = slave->poll_fd;
+       pcm->hw_ptr = slave->hw_ptr;
+       pcm->appl_ptr = slave->appl_ptr;
+       *pcmp = pcm;
+
+       return 0;
+}
+
+int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *conf)
+{
+       int err;
+       char buf[256];
+       const char *str;
+       const char *lib = NULL, *install = NULL;
+       snd_config_t *args = NULL;
+       snd_config_iterator_t i, next;
+       int (*install_func)(snd_pcm_t *pcm, snd_config_t *args);
+       void *h;
+       if (snd_config_get_string(conf, &str) >= 0) {
+               err = snd_config_search_alias(snd_config, "pcm_hook", str, &conf);
+               if (err < 0) {
+                       SNDERR("unknown pcm_hook %s", str);
+                       return err;
+               }
+       }
+       if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
+               SNDERR("Invalid hook definition");
+               return -EINVAL;
+       }
+       snd_config_for_each(i, next, conf) {
+               snd_config_t *n = snd_config_iterator_entry(i);
+               const char *id = snd_config_get_id(n);
+               if (strcmp(id, "comment") == 0)
+                       continue;
+               if (strcmp(id, "lib") == 0) {
+                       err = snd_config_get_string(n, &lib);
+                       if (err < 0) {
+                               SNDERR("Invalid type for %s", id);
+                               return -EINVAL;
+                       }
+                       continue;
+               }
+               if (strcmp(id, "install") == 0) {
+                       err = snd_config_get_string(n, &install);
+                       if (err < 0) {
+                               SNDERR("Invalid type for %s", id);
+                               return -EINVAL;
+                       }
+                       continue;
+               }
+               if (strcmp(id, "args") == 0) {
+                       args = n;
+                       continue;
+               }
+               SNDERR("Unknown field %s", id);
+               return -EINVAL;
+       }
+       if (args && snd_config_get_string(args, &str) >= 0) {
+               err = snd_config_search_alias(snd_config, "hook_args", str, &args);
+               if (err < 0) {
+                       SNDERR("unknown hook_args %s", str);
+                       return err;
+               }
+       }
+       if (!install) {
+               install = buf;
+               snprintf(buf, sizeof(buf), "_snd_pcm_hook_%s_install",
+                        snd_config_get_id(conf));
+       }
+       if (!lib)
+               lib = ALSA_LIB;
+       h = dlopen(lib, RTLD_NOW);
+       if (!h) {
+               SNDERR("Cannot open shared library %s", lib);
+               return -ENOENT;
+       }
+       install_func = dlsym(h, install);
+       if (!install_func) {
+               SNDERR("symbol %s is not defined inside %s", install, lib);
+               dlclose(h);
+               return -ENXIO;
+       }
+       err = install_func(pcm, args);
+       if (err < 0)
+               return err;
+       return 0;
+}
+
+int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
+                       snd_config_t *conf, 
+                       snd_pcm_stream_t stream, int mode)
+{
+       snd_config_iterator_t i, next;
+       int err;
+       snd_pcm_t *spcm;
+       snd_config_t *slave = NULL, *sconf;
+       snd_config_t *hooks = NULL;
+       snd_config_for_each(i, next, conf) {
+               snd_config_t *n = snd_config_iterator_entry(i);
+               const char *id = snd_config_get_id(n);
+               if (snd_pcm_conf_generic_id(id))
+                       continue;
+               if (strcmp(id, "slave") == 0) {
+                       slave = n;
+                       continue;
+               }
+               if (strcmp(id, "hooks") == 0) {
+                       if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
+                               SNDERR("Invalid type for %s", id);
+                               return -EINVAL;
+                       }
+                       hooks = n;
+                       continue;
+               }
+               SNDERR("Unknown field %s", id);
+               return -EINVAL;
+       }
+       if (!slave) {
+               SNDERR("slave is not defined");
+               return -EINVAL;
+       }
+       err = snd_pcm_slave_conf(slave, &sconf, 0);
+       if (err < 0)
+               return err;
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hooks_open(pcmp, name, spcm, 1);
+       if (err < 0) {
+               snd_pcm_close(spcm);
+               return err;
+       }
+       if (!hooks)
+               return 0;
+       snd_config_for_each(i, next, hooks) {
+               snd_config_t *n = snd_config_iterator_entry(i);
+               err = snd_pcm_hook_add_conf(*pcmp, n);
+               if (err < 0) {
+                       snd_pcm_close(*pcmp);
+                       return err;
+               }
+       }
+       return 0;
+}
+
+#endif
+
+/**
+ * \brief Get PCM handle for a PCM hook
+ * \param hook PCM hook handle
+ * \return PCM handle
+ */
+snd_pcm_t *snd_pcm_hook_get_pcm(snd_pcm_hook_t *hook)
+{
+       assert(hook);
+       return hook->pcm;
+}
+
+/**
+ * \brief Get callback function private data for a PCM hook
+ * \param hook PCM hook handle
+ * \return callback function private data
+ */
+void *snd_pcm_hook_get_private(snd_pcm_hook_t *hook)
+{
+       assert(hook);
+       return hook->private_data;
+}
+
+/**
+ * \brief Add a PCM hook at end of hooks chain
+ * \param hookp Returned PCM hook handle
+ * \param pcm PCM handle
+ * \param type PCM hook type
+ * \param func PCM hook callback function
+ * \param private_data PCM hook private data
+ * \return 0 on success otherwise a negative error code
+ *
+ * Warning: an hook callback function cannot remove an hook of the same type
+ * different from itself
+ */
+int snd_pcm_hook_add(snd_pcm_hook_t **hookp, snd_pcm_t *pcm,
+                    snd_pcm_hook_type_t type,
+                    snd_pcm_hook_func_t func, void *private_data)
+{
+       snd_pcm_hook_t *h;
+       snd_pcm_hooks_t *hooks;
+       assert(hookp && func);
+       assert(snd_pcm_type(pcm) == SND_PCM_TYPE_HOOKS);
+       h = calloc(1, sizeof(*h));
+       if (!h)
+               return -ENOMEM;
+       h->pcm = pcm;
+       h->func = func;
+       h->private_data = private_data;
+       hooks = pcm->private_data;
+       list_add_tail(&h->list, &hooks->hooks[type]);
+       *hookp = h;
+       return 0;
+}
+
+/**
+ * \brief Remove a PCM hook
+ * \param hook PCM hook handle
+ * \return 0 on success otherwise a negative error code
+ *
+ * Warning: an hook callback cannot remove an hook of the same type
+ * different from itself
+ */
+int snd_pcm_hook_remove(snd_pcm_hook_t *hook)
+{
+       assert(hook);
+       list_del(&hook->list);
+       free(hook);
+       return 0;
+}
+
index 1c1e51a..f90fd4d 100644 (file)
@@ -669,9 +669,7 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "card") == 0) {
                        err = snd_config_get_integer(n, &card);
index d4f9cb7..1384cf7 100644 (file)
@@ -337,9 +337,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index af82797..a890708 100644 (file)
@@ -31,6 +31,7 @@
 #define _snd_pcm_subformat_mask _snd_mask
 
 #include "local.h"
+#include "list.h"
 
 #define SND_INTERVAL_INLINE
 #include "interval.h"
@@ -169,7 +170,6 @@ struct _snd_pcm {
        snd_pcm_channel_info_t *mmap_channels;
        snd_pcm_channel_area_t *running_areas;
        snd_pcm_channel_area_t *stopped_areas;
-       void *stopped;
        snd_pcm_ops_t *ops;
        snd_pcm_fast_ops_t *fast_ops;
        snd_pcm_t *op_arg;
@@ -532,6 +532,7 @@ int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf,
 
 int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *conf,
                       snd_pcm_stream_t stream, int mode);
+int snd_pcm_conf_generic_id(const char *id);
 
 #define SND_PCM_HW_PARBIT_ACCESS       (1U << SND_PCM_HW_PARAM_ACCESS)
 #define SND_PCM_HW_PARBIT_FORMAT       (1U << SND_PCM_HW_PARAM_FORMAT)
index 28bbe66..77259ba 100644 (file)
@@ -653,6 +653,18 @@ static int snd_pcm_meter_add_scope_conf(snd_pcm_t *pcm, const char *name,
                         snd_config_t *);
        void *h;
        int err;
+       err = snd_config_get_string(conf, &str);
+       if (err >= 0) {
+               err = snd_config_search_alias(snd_config, "pcm_scope", str, &conf);
+               if (err < 0) {
+                       SNDERR("unknown pcm_scope %s", str);
+                       return err;
+               }
+       }
+       if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
+               SNDERR("Invalid type for scope %s", str);
+               return -EINVAL;
+       }
        err = snd_config_search(conf, "type", &c);
        if (err < 0) {
                SNDERR("type is not defined");
@@ -695,7 +707,7 @@ static int snd_pcm_meter_add_scope_conf(snd_pcm_t *pcm, const char *name,
                snprintf(buf, sizeof(buf), "_snd_pcm_scope_%s_open", str);
        }
        if (!lib)
-               lib = "libasound.so";
+               lib = ALSA_LIB;
        h = dlopen(lib, RTLD_NOW);
        if (!h) {
                SNDERR("Cannot open shared library %s", lib);
@@ -724,9 +736,7 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
@@ -762,8 +772,10 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
        if (err < 0)
                return err;
        err = snd_pcm_meter_open(pcmp, name, frequency > 0 ? (unsigned int) frequency : FREQUENCY, spcm, 1);
-       if (err < 0)
+       if (err < 0) {
                snd_pcm_close(spcm);
+               return err;
+       }
        if (!scopes)
                return 0;
        snd_config_for_each(i, next, scopes) {
@@ -772,7 +784,7 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
                err = snd_pcm_meter_add_scope_conf(*pcmp, id, n);
                if (err < 0) {
                        snd_pcm_close(*pcmp);
-                       return -EINVAL;
+                       return err;
                }
        }
        return 0;
diff --git a/src/pcm/pcm_meter.h b/src/pcm/pcm_meter.h
deleted file mode 100644 (file)
index aef020f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- *  PCM - Meter plugin
- *  Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
- *
- *   This library is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU Library General Public License as
- *   published by the Free Software Foundation; either version 2 of
- *   the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU Library General Public License for more details.
- *
- *   You should have received a copy of the GNU Library General Public
- *   License along with this library; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
index 9f30793..7d921e3 100644 (file)
@@ -447,9 +447,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index 65e0d45..e8e7359 100644 (file)
@@ -665,9 +665,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        snd_config_for_each(i, inext, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slaves") == 0) {
                        if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
index 387ad4c..402ff9a 100644 (file)
@@ -372,9 +372,7 @@ int _snd_pcm_null_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                SNDERR("Unknown field %s", id);
                return -EINVAL;
index ac7099c..380ef05 100644 (file)
@@ -2067,7 +2067,7 @@ int _snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        if (pcm->setup) {
                err = snd_pcm_hw_free(pcm);
                if (err < 0)
-                       return 0;
+                       return err;
        }
        err = pcm->ops->hw_params(pcm->op_arg, params);
        if (err < 0)
@@ -2110,6 +2110,8 @@ int _snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
            pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX) {
                err = snd_pcm_mmap(pcm);
        }
-       return err;
+       if (err < 0)
+               return err;
+       return 0;
 }
 
index 3c18d71..3a6f615 100644 (file)
@@ -724,9 +724,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index 236532d..743c367 100644 (file)
@@ -547,9 +547,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index 95299f5..b4c6efc 100644 (file)
@@ -854,9 +854,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        slave = n;
index c1ca99b..ad133f3 100644 (file)
@@ -1387,9 +1387,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "slave") == 0) {
                        err = snd_config_get_string(n, &slave_name);
index 4b87ed2..4173b83 100644 (file)
@@ -735,9 +735,7 @@ int _snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "server") == 0) {
                        err = snd_config_get_string(n, &server);
index ec94b16..b8b5bc2 100644 (file)
@@ -1035,9 +1035,7 @@ int _snd_pcm_surround_open(snd_pcm_t **pcmp, const char *name, snd_config_t *con
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
-               if (strcmp(id, "comment") == 0)
-                       continue;
-               if (strcmp(id, "type") == 0)
+               if (snd_pcm_conf_generic_id(id))
                        continue;
                if (strcmp(id, "card") == 0) {
                        err = snd_config_get_integer(n, &card);
index 5603176..4741750 100644 (file)
@@ -127,7 +127,7 @@ int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
                snprintf(buf, sizeof(buf), "_snd_rawmidi_%s_open", str);
        }
        if (!lib)
-               lib = "libasound.so";
+               lib = ALSA_LIB;
        h = dlopen(lib, RTLD_NOW);
        if (!h) {
                SNDERR("Cannot open shared library %s", lib);
index 8de8449..c017925 100644 (file)
@@ -102,7 +102,7 @@ static int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
                snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
        }
        if (!lib)
-               lib = "libasound.so";
+               lib = ALSA_LIB;
        h = dlopen(lib, RTLD_NOW);
        if (!h) {
                SNDERR("Cannot open shared library %s", lib);