OSDN Git Service

Moved some prototypes from src/pcm/pcm_plugin.h to include/pcm_plugin.h.
authorJaroslav Kysela <perex@perex.cz>
Sat, 12 Jan 2002 10:52:42 +0000 (10:52 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sat, 12 Jan 2002 10:52:42 +0000 (10:52 +0000)
Merged src/pcm/atomic.h to include/iatomic.h.
Added initial description of hw and hooks plugins.

18 files changed:
doc/doxygen.cfg
doc/index.doxygen
include/Makefile.am
include/iatomic.h
include/local.h
include/pcm_plugin.h [new file with mode: 0644]
src/conf.c
src/pcm/Makefile.am
src/pcm/atomic.c
src/pcm/atomic.h [deleted file]
src/pcm/pcm_hooks.c
src/pcm/pcm_hw.c
src/pcm/pcm_local.h
src/pcm/pcm_plug.c
src/pcm/pcm_plugin.c
src/pcm/pcm_plugin.h
src/pcm/pcm_rate.c
src/pcm/pcm_route.c

index 5bc0c55..8a52090 100644 (file)
@@ -25,7 +25,27 @@ INPUT            = index.doxygen \
                   ../include/seq_midi_event.h \
                   ../include/conv.h \
                   ../include/instr.h \
-                  ../src
+                  ../src/error.c \
+                  ../src/dlmisc.c \
+                  ../src/async.c \
+                  ../src/input.c \
+                  ../src/output.c \
+                  ../src/conf.c \
+                  ../src/confmisc.c \
+                  ../src/control \
+                  ../src/mixer \
+                  ../src/pcm/pcm.c \
+                  ../src/pcm/pcm_mmap.c \
+                   ../src/pcm/pcm_plugin.c \
+                  ../src/pcm/pcm_hw.c \
+                  ../src/pcm/pcm_hooks.c \
+                  ../src/pcm/pcm_meter.c \
+                  ../src/pcm/pcm_misc.c \
+                  ../src/rawmidi \
+                  ../src/timer \
+                  ../src/hwdep \
+                  ../src/seq \
+                  ../src/instr
 EXCLUDE                 = ../src/control/control_local.h \
                   ../src/pcm/atomic.h \
                   ../src/pcm/interval.h \
index 183cca5..1c445d1 100644 (file)
@@ -31,6 +31,7 @@ may be placed in the library code instead of the kernel driver.</P>
 
 <UL>
   <LI>Page \ref pcm explains the design of PCM (digital audio) API
+  <LI>Page \ref pcm_plugins explains the design of PCM (digital audio) plugins
 </UL>
 
 <H2>Configuration</H2>
index 0a41c07..9d847f5 100644 (file)
@@ -3,12 +3,12 @@ alsaincludedir = ${includedir}/alsa
 
 alsainclude_HEADERS = asoundlib.h asoundef.h \
                      version.h global.h input.h output.h error.h \
-                     conf.h pcm.h rawmidi.h timer.h \
+                     conf.h pcm.h pcm_plugin.h rawmidi.h timer.h \
                      hwdep.h control.h mixer.h \
                      seq_event.h seq.h seqmid.h seq_midi_event.h \
-                     conv.h instr.h
+                     conv.h instr.h iatomic.h
 
-noinst_HEADERS = sys.h search.h list.h aserver.h local.h config.h iatomic.h
+noinst_HEADERS = sys.h search.h list.h aserver.h local.h config.h
 
 EXTRA_CLEAN = stamp-vh
 
index 6f697a6..6d7f546 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ALSA_IATOMIC__
-#define __ALSA_IATOMIC__
+#ifndef __ALSA_IATOMIC_H
+#define __ALSA_IATOMIC_H
 
 #ifdef __i386__
 
@@ -1059,4 +1059,72 @@ typedef struct { volatile int counter; } atomic_t;
 
 #endif /* IATOMIC_DEFINED */
 
-#endif /* __ALSA_IATOMIC__ */
+/*
+ *  Atomic read/write
+ *  Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
+ */
+
+/* Max number of times we must spin on a spinlock calling sched_yield().
+   After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */
+
+#ifndef MAX_SPIN_COUNT
+#define MAX_SPIN_COUNT 50
+#endif
+
+/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
+   after MAX_SPIN_COUNT iterations of sched_yield().
+   This MUST BE > 2ms.
+   (Otherwise the kernel does busy-waiting for realtime threads,
+    giving other threads no chance to run.) */
+
+#ifndef SPIN_SLEEP_DURATION
+#define SPIN_SLEEP_DURATION 2000001
+#endif
+
+typedef struct {
+       unsigned int begin, end;
+} snd_atomic_write_t;
+
+typedef struct {
+       volatile const snd_atomic_write_t *write;
+       unsigned int end;
+} snd_atomic_read_t;
+
+void snd_atomic_read_wait(snd_atomic_read_t *t);
+
+static inline void snd_atomic_write_init(snd_atomic_write_t *w)
+{
+       w->begin = 0;
+       w->end = 0;
+}
+
+static inline void snd_atomic_write_begin(snd_atomic_write_t *w)
+{
+       w->begin++;
+       wmb();
+}
+
+static inline void snd_atomic_write_end(snd_atomic_write_t *w)
+{
+       wmb();
+       w->end++;
+}
+
+static inline void snd_atomic_read_init(snd_atomic_read_t *r, snd_atomic_write_t *w)
+{
+       r->write = w;
+}
+
+static inline void snd_atomic_read_begin(snd_atomic_read_t *r)
+{
+       r->end = r->write->end;
+       rmb();
+}
+
+static inline int snd_atomic_read_ok(snd_atomic_read_t *r)
+{
+       rmb();
+       return r->end == r->write->begin;
+}
+
+#endif /* __ALSA_IATOMIC_H */
index 4f43edc..5151780 100644 (file)
@@ -93,6 +93,7 @@ typedef struct sndrv_seq_event snd_seq_event_t;
 #include "error.h"
 #include "conf.h"
 #include "pcm.h"
+#include "pcm_plugin.h"
 #include "rawmidi.h"
 #include "timer.h"
 #include "hwdep.h"
diff --git a/include/pcm_plugin.h b/include/pcm_plugin.h
new file mode 100644 (file)
index 0000000..db4f163
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * \file <alsa/pcm_plugin.h>
+ * \brief Common PCM plugin code
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \date 2000-2001
+ *
+ * Application interface library for the ALSA driver.
+ * See the \ref pcm_plugins page for more details.
+ *
+ * \warning Using of contents of this header file might be dangerous
+ *         in the sense of compatibility reasons. The contents might be
+ *         freely changed in future.
+ *
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as
+ *   published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_PCM_PLUGIN_H
+
+/**
+ * \defgroup PCM_Plugins PCM Plugins
+ * \ingroup PCM
+ * See the \ref pcm_plugins page for more details.
+ * \{
+ */
+  
+#define SND_PCM_PLUGIN_RATE_MIN 4000   /**< minimal rate for the rate plugin */
+#define SND_PCM_PLUGIN_RATE_MAX 192000 /**< maximal rate for the rate plugin */
+
+#define SND_PCM_PLUGIN_ROUTE_FLOAT 1      /**< use floats for route plugin */
+#define SND_PCM_PLUGIN_ROUTE_RESOLUTION 16 /**< integer resolution for route plugin */
+
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
+/** route ttable entry type */
+typedef float snd_pcm_route_ttable_entry_t;
+#define SND_PCM_PLUGIN_ROUTE_HALF 0.5  /**< half value */
+#define SND_PCM_PLUGIN_ROUTE_FULL 1.0  /**< full value */
+#else
+/** route ttable entry type */
+typedef int snd_pcm_route_ttable_entry_t;
+#define SND_PCM_PLUGIN_ROUTE_HALF (SND_PCM_PLUGIN_ROUTE_RESOLUTION / 2)        /**< half value */
+#define SND_PCM_PLUGIN_ROUTE_FULL SND_PCM_PLUGIN_ROUTE_RESOLUTION      /**< full value */
+#endif
+
+/*
+ *  Hardware plugin
+ */
+int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
+                   int card, int device, int subdevice,
+                   snd_pcm_stream_t stream, int mode,
+                   int mmap_emulation);
+int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
+                    snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
+                    snd_pcm_stream_t stream, int mode);
+
+int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
+                     snd_pcm_t *slave, int close_slave);
+int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
+                       snd_pcm_format_t sformat, snd_pcm_t *slave,
+                       int close_slave);
+int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name,
+                       snd_pcm_format_t sformat, snd_pcm_t *slave,
+                       int close_slave);
+int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
+                      snd_pcm_format_t sformat, snd_pcm_t *slave,
+                      int close_slave);
+int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
+                     snd_pcm_format_t sformat, snd_pcm_t *slave,
+                     int close_slave);
+int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
+                      snd_pcm_format_t sformat, snd_pcm_t *slave,
+                      int close_slave);
+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 snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
+                      snd_pcm_format_t sformat, int schannels,
+                      snd_pcm_route_ttable_entry_t *ttable,
+                      unsigned int tt_ssize,
+                      unsigned int tt_cused, unsigned int tt_sused,
+                      snd_pcm_t *slave, int close_slave);
+int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
+                     snd_pcm_format_t sformat, unsigned int srate,
+                     snd_pcm_t *slave, int close_slave);
+
+/*
+ *  Hooks plugin
+ */
+int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
+                      snd_pcm_t *slave, int close_slave);
+int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
+                       snd_config_t *root, snd_config_t *conf,
+                       snd_pcm_stream_t stream, int mode);
+
+/** \} */
+
+#endif /* __ALSA_PCM_PLUGIN_H */
index 7a3b491..313cd00 100644 (file)
@@ -239,7 +239,7 @@ with new contents. This mode is specified with a prefix char note of
 exclamation (!).
 
 \code
-!defaults.pcm.device 1
+defaults.pcm.!device 1
 \endcode
 
 \section conf_syntax_summary Syntax summary
index 24f8b1d..551c80d 100644 (file)
@@ -8,7 +8,7 @@ libpcm_la_SOURCES = atomic.c mask.c interval.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_hooks.c pcm_lfloat.c pcm_ladspa.c pcm_symbols.c
-noinst_HEADERS = atomic.h pcm_local.h pcm_plugin.h mask.h mask_inline.h \
+noinst_HEADERS = pcm_local.h pcm_plugin.h mask.h mask_inline.h \
                 interval.h interval_inline.h plugin_ops.h ladspa.h
 
 alsadir = $(datadir)/alsa
index 4896b5c..7565945 100644 (file)
@@ -21,7 +21,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <sched.h>
-#include "atomic.h"
+#include "iatomic.h"
 
 void snd_atomic_read_wait(snd_atomic_read_t *t)
 {
diff --git a/src/pcm/atomic.h b/src/pcm/atomic.h
deleted file mode 100644 (file)
index 946bd29..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Atomic read/write
- *  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 Lesser General Public License as
- *   published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public
- *   License along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#include "iatomic.h"
-
-/* Max number of times we must spin on a spinlock calling sched_yield().
-   After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */
-
-#ifndef MAX_SPIN_COUNT
-#define MAX_SPIN_COUNT 50
-#endif
-
-/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
-   after MAX_SPIN_COUNT iterations of sched_yield().
-   This MUST BE > 2ms.
-   (Otherwise the kernel does busy-waiting for realtime threads,
-    giving other threads no chance to run.) */
-
-#ifndef SPIN_SLEEP_DURATION
-#define SPIN_SLEEP_DURATION 2000001
-#endif
-
-typedef struct {
-       unsigned int begin, end;
-} snd_atomic_write_t;
-
-typedef struct {
-       volatile const snd_atomic_write_t *write;
-       unsigned int end;
-} snd_atomic_read_t;
-
-void snd_atomic_read_wait(snd_atomic_read_t *t);
-
-static inline void snd_atomic_write_init(snd_atomic_write_t *w)
-{
-       w->begin = 0;
-       w->end = 0;
-}
-
-static inline void snd_atomic_write_begin(snd_atomic_write_t *w)
-{
-       w->begin++;
-       wmb();
-}
-
-static inline void snd_atomic_write_end(snd_atomic_write_t *w)
-{
-       wmb();
-       w->end++;
-}
-
-static inline void snd_atomic_read_init(snd_atomic_read_t *r, snd_atomic_write_t *w)
-{
-       r->write = w;
-}
-
-static inline void snd_atomic_read_begin(snd_atomic_read_t *r)
-{
-       r->end = r->write->end;
-       rmb();
-}
-
-static inline int snd_atomic_read_ok(snd_atomic_read_t *r)
-{
-       rmb();
-       return r->end == r->write->begin;
-}
-
index 4c9bf65..a1d1dd2 100644 (file)
@@ -1,3 +1,11 @@
+/**
+ * \file pcm/pcm_hooks.c
+ * \ingroup PCM_Hook
+ * \brief PCM Hook Interface
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \date 2000-2001
+ */
 /*
  *  PCM - Hook functions
  *  Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
@@ -40,6 +48,7 @@ typedef struct {
        int close_slave;
        struct list_head hooks[SND_PCM_HOOK_TYPE_LAST + 1];
 } snd_pcm_hooks_t;
+#endif
 
 static int snd_pcm_hooks_close(snd_pcm_t *pcm)
 {
@@ -265,7 +274,7 @@ static void snd_pcm_hooks_dump(snd_pcm_t *pcm, snd_output_t *out)
        snd_pcm_dump(h->slave, out);
 }
 
-snd_pcm_ops_t snd_pcm_hooks_ops = {
+static 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,
@@ -280,7 +289,7 @@ snd_pcm_ops_t snd_pcm_hooks_ops = {
        munmap: snd_pcm_hooks_munmap,
 };
 
-snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
+static 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,
@@ -300,6 +309,17 @@ snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
        mmap_commit: snd_pcm_hooks_mmap_commit,
 };
 
+/**
+ * \brief Creates a new hooks PCM
+ * \param pcmp Returns created PCM handle
+ * \param name Name of PCM
+ * \param slave Slave PCM
+ * \param close_slave If set, slave PCM handle is closed when hooks PCM is closed
+ * \retval zero on success otherwise a negative error code
+ * \warning Using of this function might be dangerous in the sense
+ *          of compatibility reasons. The prototype might be freely
+ *         changed in future.
+ */
 int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int close_slave)
 {
        snd_pcm_t *pcm;
@@ -331,6 +351,81 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
        return 0;
 }
 
+/*! \page pcm_plugins
+
+\section pcm_plugins_hooks Plugin: hooks
+
+\code
+# Hook arguments definition
+hook_args.NAME {
+       ...                     # Arbitrary arguments
+}
+
+# PCM hook type
+pcm_hook_type.NAME {
+       [lib STR]               # Library file (default libasound.so)
+       [install STR]           # Install function (default _snd_pcm_hook_NAME_install)
+}
+
+# PCM hook definition
+pcm_hook.NAME {
+       type STR                # PCM Hook type (see pcm_hook_type)
+       [args STR]              # Arguments for install function (see hook_args)
+       # or
+       [args { }]              # Arguments for install function
+}
+
+# PCM hook plugin
+pcm.NAME {
+       type hooks              # PCM with hooks
+       slave STR               # Slave name
+       # 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)
+       }
+}
+\endcode
+
+Example:
+
+\code
+       hooks.0 {
+               type ctl_elems
+               hook_args [
+                       {
+                               name "Wave Surround Playback Volume"
+                               preserve true
+                               lock true
+                               value [ 0 0 ]
+                       }
+                       {
+                               name "EMU10K1 PCM Send Volume"
+                               index { @func private_pcm_subdevice }
+                               lock true
+                               value [ 0 0 0 0 0 0 255 0 0 0 0 255 ]
+                       }
+               ]
+       }
+\endcode
+
+\subsection pcm_plugins_hooks_funcref Function reference
+
+<UL>
+  <LI>The function ctl_elems - _snd_pcm_hook_ctl_elems_install() - installs
+      CTL settings described by given configuration.
+  <LI>snd_pcm_hooks_open()
+  <LI>_snd_pcm_hooks_open()
+</UL>
+
+*/
+
 static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_t *conf)
 {
        int err;
@@ -444,6 +539,19 @@ static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_
        return 0;
 }
 
+/**
+ * \brief Creates a new hooks PCM
+ * \param pcmp Returns created PCM handle
+ * \param name Name of PCM
+ * \param root Root configuration node
+ * \param conf Configuration node with hooks PCM description
+ * \param stream PCM Stream
+ * \param mode PCM Mode
+ * \retval zero on success otherwise a negative error code
+ * \warning Using of this function might be dangerous in the sense
+ *          of compatibility reasons. The prototype might be freely
+ *         changed in future.
+ */
 int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
                        snd_config_t *root, snd_config_t *conf, 
                        snd_pcm_stream_t stream, int mode)
@@ -514,8 +622,8 @@ int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
        *pcmp = rpcm;
        return 0;
 }
+#ifndef DOC_HIDDEN
 SND_DLSYM_BUILD_VERSION(_snd_pcm_hooks_open, SND_PCM_DLSYM_VERSION);
-
 #endif
 
 /**
@@ -623,6 +731,12 @@ static int snd_pcm_hook_ctl_elems_close(snd_pcm_hook_t *hook)
        return err;
 }
 
+/**
+ * \brief Install CTL settings using hardware associated with PCM handle
+ * \param pcm PCM handle
+ * \param conf Configuration node with CTL settings
+ * \return zero on success otherwise a negative error code
+ */
 int _snd_pcm_hook_ctl_elems_install(snd_pcm_t *pcm, snd_config_t *conf)
 {
        int err;
index e295312..13c3245 100644 (file)
@@ -1,3 +1,11 @@
+/**
+ * \file pcm/pcm_hw.c
+ * \ingroup PCM_Plugins
+ * \brief PCM HW Interface
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \date 2000-2001
+ */
 /*
  *  PCM - Hardware
  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@@ -36,6 +44,8 @@
 const char *_snd_module_pcm_hw = "";
 #endif
 
+#ifndef DOC_HIDDEN
+
 #ifndef F_SETSIG
 #define F_SETSIG 10
 #endif
@@ -62,6 +72,8 @@ typedef struct {
        do { if (hw->shadow_appl_ptr && !hw->avail_update_flag) \
               hw->appl_ptr = hw->mmap_control->appl_ptr; } while (0)
 
+#endif /* DOC_HIDDEN */
+
 static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
 {
        long flags;
@@ -643,7 +655,7 @@ static void snd_pcm_hw_dump(snd_pcm_t *pcm, snd_output_t *out)
        }
 }
 
-snd_pcm_ops_t snd_pcm_hw_ops = {
+static snd_pcm_ops_t snd_pcm_hw_ops = {
        close: snd_pcm_hw_close,
        info: snd_pcm_hw_info,
        hw_refine: snd_pcm_hw_hw_refine,
@@ -658,7 +670,7 @@ snd_pcm_ops_t snd_pcm_hw_ops = {
        munmap: snd_pcm_hw_munmap,
 };
 
-snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
+static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        status: snd_pcm_hw_status,
        state: snd_pcm_hw_state,
        delay: snd_pcm_hw_delay,
@@ -678,6 +690,20 @@ snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        mmap_commit: snd_pcm_hw_mmap_commit,
 };
 
+/**
+ * \brief Creates a new hw PCM
+ * \param pcmp Returns created PCM handle
+ * \param name Name of PCM
+ * \param card Number of card
+ * \param device Number of device
+ * \param subdevice Number of subdevice
+ * \param stream PCM Stream
+ * \param mode PCM Mode
+ * \retval zero on success otherwise a negative error code
+ * \warning Using of this function might be dangerous in the sense
+ *          of compatibility reasons. The prototype might be freely
+ *          changed in future.
+ */
 int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
                    int card, int device, int subdevice,
                    snd_pcm_stream_t stream, int mode,
@@ -795,6 +821,45 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
        return ret;
 }
 
+/*! \page pcm_plugins
+
+\section pcm_plugins_hw Plugin: hw
+
+This plugin communicates directly with the ALSA kernel driver. It is a raw
+communication without any conversions. The emulation of mmap access can be
+optionally enabled, but expect a worse latency in the case.
+
+\code
+pcm.name {
+       type hw                 # Kernel PCM
+       card INT/STR            # Card name (string) or number (integer)
+       [device INT]            # Device number (default 0)
+       [subdevice INT]         # Subdevice number (default -1: first available)
+       [mmap_emulation BOOL]   # Enable mmap emulation for ro/wo devices
+}
+\endcode
+
+\subsection pcm_plugins_hw_funcref Function reference
+
+<UL>
+  <LI>snd_pcm_hw_open()
+  <LI>_snd_pcm_hw_open()
+</UL>
+
+*/
+
+/**
+ * \brief Creates a new hw PCM
+ * \param pcmp Returns created PCM handle
+ * \param name Name of PCM
+ * \param root Root configuration node
+ * \param conf Configuration node with hw PCM description
+ * \param stream PCM Stream
+ * \param mode PCM Mode
+ * \warning Using of this function might be dangerous in the sense
+ *          of compatibility reasons. The prototype might be freely
+ *          changed in future.
+ */
 int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
                     snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
                     snd_pcm_stream_t stream, int mode)
@@ -858,4 +923,6 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
        }
        return snd_pcm_hw_open(pcmp, name, card, device, subdevice, stream, mode, mmap_emulation);
 }
+#ifndef DOC_HIDDEN
 SND_DLSYM_BUILD_VERSION(_snd_pcm_hw_open, SND_PCM_DLSYM_VERSION);
+#endif
index a7cb60c..96de21b 100644 (file)
@@ -193,19 +193,6 @@ struct _snd_pcm {
        struct list_head async_handlers;
 };
 
-#define ROUTE_PLUGIN_FLOAT 1
-#define ROUTE_PLUGIN_RESOLUTION 16
-
-#if ROUTE_PLUGIN_FLOAT
-typedef float snd_pcm_route_ttable_entry_t;
-#define HALF 0.5
-#define FULL 1.0
-#else
-typedef int snd_pcm_route_ttable_entry_t;
-#define HALF (ROUTE_PLUGIN_RESOLUTION / 2)
-#define FULL ROUTE_PLUGIN_RESOLUTION
-#endif
-
 /* FIXME */
 #define _snd_pcm_link_descriptor _snd_pcm_poll_descriptor
 #define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor
index 19e93a6..8aaf56d 100644 (file)
@@ -333,7 +333,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
                                n = slv->channels;
                        }
                        while (n-- > 0) {
-                               snd_pcm_route_ttable_entry_t v = FULL;
+                               snd_pcm_route_ttable_entry_t v = SND_PCM_PLUGIN_ROUTE_FULL;
                                if (rpolicy == PLUG_ROUTE_POLICY_AVERAGE) {
                                        if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
                                            clt->channels > slv->channels) {
@@ -363,7 +363,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
                                n = slv->channels;
                        }
                        for (c = 0; (int)c < n; c++)
-                               ttable[c * tt_ssize + c] = FULL;
+                               ttable[c * tt_ssize + c] = SND_PCM_PLUGIN_ROUTE_FULL;
                        break;
                default:
                        SNDERR("Invalid route policy");
index 23a7ae8..0353dff 100644 (file)
@@ -1,3 +1,11 @@
+/**
+ * \file pcm/pcm_plugin.c
+ * \ingroup PCM
+ * \brief PCM Interface
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \date 2000-2001
+ */
 /*
  *  PCM - Common plugin code
  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
  */
+/*!
+ * \page pcm_plugins PCM (digital audio) plugins
+ * 
+ * PCM plugins extends functionality and features of PCM devices.
+ * The plugins take care about various sample conversions, sample
+ * copying among channels and so on.
+ */
   
 #include <sys/shm.h>
 #include <limits.h>
 #include "pcm_local.h"
 #include "pcm_plugin.h"
 
+#ifndef DOC_HIDDEN
+
 int snd_pcm_plugin_close(snd_pcm_t *pcm)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
@@ -481,3 +498,5 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
        mmap_commit: snd_pcm_plugin_mmap_commit,
 };
 
+
+#endif
index 0ab8988..a329724 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
   
-#include "atomic.h"
+#include "iatomic.h"
 
 typedef snd_pcm_uframes_t (*snd_pcm_slave_xfer_areas_func_t)
      (snd_pcm_t *pcm, 
@@ -79,30 +79,9 @@ int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
 
 extern snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
 
-#define RATE_MIN 4000
-#define RATE_MAX 192000
-
 int snd_pcm_linear_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
 int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
 int snd_pcm_linear_convert_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format);
-int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int close_slave);
-int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
-int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
-int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
-int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
-int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave);
-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 snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
-                      snd_pcm_format_t sformat, int schannels,
-                      snd_pcm_route_ttable_entry_t *ttable,
-                      unsigned int tt_ssize,
-                      unsigned int tt_cused, unsigned int tt_sused,
-                      snd_pcm_t *slave, int close_slave);
-int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, unsigned int srate, snd_pcm_t *slave, int close_slave);
-
 
 void snd_pcm_linear_convert(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
                            const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
index 2ca4ec9..3d817bc 100644 (file)
@@ -229,11 +229,11 @@ static int snd_pcm_rate_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_
        if (err < 0)
                return err;
        err = _snd_pcm_hw_param_set_min(params,
-                                       SND_PCM_HW_PARAM_RATE, RATE_MIN, 0);
+                                       SND_PCM_HW_PARAM_RATE, SND_PCM_PLUGIN_RATE_MIN, 0);
        if (err < 0)
                return err;
        err = _snd_pcm_hw_param_set_max(params,
-                                       SND_PCM_HW_PARAM_RATE, RATE_MAX, 0);
+                                       SND_PCM_HW_PARAM_RATE, SND_PCM_PLUGIN_RATE_MAX, 0);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
index 1964004..37177c9 100644 (file)
@@ -30,9 +30,9 @@ const char *_snd_module_pcm_route = "";
 #endif
 
 /* The best possible hack to support missing optimization in gcc 2.7.2.3 */
-#if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0
-#define div(a) a /= ROUTE_PLUGIN_RESOLUTION
-#elif ROUTE_PLUGIN_RESOLUTION == 16
+#if SND_PCM_PLUGIN_ROUTE_RESOLUTION & (SND_PCM_PLUGIN_ROUTE_RESOLUTION - 1) != 0
+#define div(a) a /= SND_PCM_PLUGIN_ROUTE_RESOLUTION
+#elif SND_PCM_PLUGIN_ROUTE_RESOLUTION == 16
 #define div(a) a >>= 4
 #else
 #error "Add some code here"
@@ -41,7 +41,7 @@ const char *_snd_module_pcm_route = "";
 typedef struct {
        int channel;
        int as_int;
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
        float as_float;
 #endif
 } snd_pcm_route_ttable_src_t;
@@ -78,7 +78,7 @@ struct snd_pcm_route_ttable_dst {
 typedef union {
        int32_t as_sint32;
        int64_t as_sint64;
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
        float as_float;
 #endif
 } sum_t;
@@ -163,7 +163,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
 #undef PUT32_LABELS
        static void *zero_labels[3] = {
                &&zero_int32, &&zero_int64,
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
                &&zero_float
 #endif
        };
@@ -171,7 +171,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
        static void *add_labels[3 * 2] = {
                &&add_int32_noatt, &&add_int32_att,
                &&add_int64_noatt, &&add_int64_att,
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
                &&add_float_noatt, &&add_float_att
 #endif
        };
@@ -193,7 +193,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
                &&norm_int64_8_att,
                &&norm_int64_16_att,
                &&norm_int64_24_att,
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
                &&norm_float_0,
                &&norm_float_8,
                &&norm_float_16,
@@ -226,7 +226,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
                                            src_areas, src_offset,
                                            frames, ttable, params);
                return;
-       } else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
+       } else if (nsrcs == 1 && src_tt[0].as_int == SND_PCM_PLUGIN_ROUTE_RESOLUTION) {
                snd_pcm_route_convert1_one(dst_area, dst_offset,
                                           src_areas, src_offset,
                                           frames, ttable, params);
@@ -253,7 +253,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
        zero_int64: 
                sum.as_sint64 = 0;
                goto zero_end;
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
        zero_float:
                sum.as_float = 0.0;
                goto zero_end;
@@ -285,7 +285,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
                        if (ttp->as_int)
                                sum.as_sint64 += sample;
                        goto after_sum;
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
                add_float_att:
                        sum.as_float += sample * ttp->as_float;
                        goto after_sum;
@@ -349,7 +349,7 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
                        sample = sum.as_sint64;
                goto after_norm;
 
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
        norm_float_8:
                sum.as_float *= 1 << 8;
                goto norm_float;
@@ -552,7 +552,7 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        route->params.conv_idx = snd_pcm_linear_convert_index(src_format, dst_format);
        route->params.src_size = snd_pcm_format_width(src_format) / 8;
        route->params.dst_sfmt = dst_format;
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
        route->params.sum_idx = FLOAT;
 #else
        if (snd_pcm_format_width(src_format) == 32)
@@ -624,10 +624,10 @@ 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
+#if SND_PCM_PLUGIN_ROUTE_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);
+                               snd_output_printf(out, "%d*%g", s->channel, (double)s->as_int / (double)SND_PCM_PLUGIN_ROUTE_RESOLUTION);
 #endif
                        else
                                snd_output_printf(out, "%d", s->channel);
@@ -693,24 +693,24 @@ static int route_load_ttable(snd_pcm_route_params_t *params, snd_pcm_stream_t st
                for (src_channel = 0; src_channel < sused; ++src_channel) {
                        snd_pcm_route_ttable_entry_t v;
                        v = ttable[src_channel * smul + dst_channel * dmul];
-                       assert(v >= 0 && v <= FULL);
+                       assert(v >= 0 && v <= SND_PCM_PLUGIN_ROUTE_FULL);
                        if (v != 0) {
                                srcs[nsrcs].channel = src_channel;
-#if ROUTE_PLUGIN_FLOAT
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
                                /* Also in user space for non attenuated */
-                               srcs[nsrcs].as_int = (v == FULL ? ROUTE_PLUGIN_RESOLUTION : 0);
+                               srcs[nsrcs].as_int = (v == SND_PCM_PLUGIN_ROUTE_FULL ? SND_PCM_PLUGIN_ROUTE_RESOLUTION : 0);
                                srcs[nsrcs].as_float = v;
 #else
                                srcs[nsrcs].as_int = v;
 #endif
-                               if (v != FULL)
+                               if (v != SND_PCM_PLUGIN_ROUTE_FULL)
                                        att = 1;
                                t += v;
                                nsrcs++;
                        }
                }
 #if 0
-               assert(t <= FULL);
+               assert(t <= SND_PCM_PLUGIN_ROUTE_FULL);
 #endif
                dptr->att = att;
                dptr->nsrcs = nsrcs;