Merged src/pcm/atomic.h to include/iatomic.h.
Added initial description of hw and hooks plugins.
../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 \
<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>
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
-#ifndef __ALSA_IATOMIC__
-#define __ALSA_IATOMIC__
+#ifndef __ALSA_IATOMIC_H
+#define __ALSA_IATOMIC_H
#ifdef __i386__
#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 */
#include "error.h"
#include "conf.h"
#include "pcm.h"
+#include "pcm_plugin.h"
#include "rawmidi.h"
#include "timer.h"
#include "hwdep.h"
--- /dev/null
+/**
+ * \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 */
exclamation (!).
\code
-!defaults.pcm.device 1
+defaults.pcm.!device 1
\endcode
\section conf_syntax_summary Syntax summary
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
#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)
{
+++ /dev/null
-/*
- * 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;
-}
-
+/**
+ * \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>
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)
{
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,
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,
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;
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;
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)
*pcmp = rpcm;
return 0;
}
+#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_hooks_open, SND_PCM_DLSYM_VERSION);
-
#endif
/**
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;
+/**
+ * \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>
const char *_snd_module_pcm_hw = "";
#endif
+#ifndef DOC_HIDDEN
+
#ifndef F_SETSIG
#define F_SETSIG 10
#endif
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;
}
}
-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,
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,
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,
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)
}
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
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
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) {
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");
+/**
+ * \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;
mmap_commit: snd_pcm_plugin_mmap_commit,
};
+
+#endif
*
*/
-#include "atomic.h"
+#include "iatomic.h"
typedef snd_pcm_uframes_t (*snd_pcm_slave_xfer_areas_func_t)
(snd_pcm_t *pcm,
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,
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);
#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"
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;
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;
#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
};
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
};
&&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,
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);
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;
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;
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;
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)
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);
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;