]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Added jack plugin
authorJaroslav Kysela <perex@perex.cz>
Wed, 12 Feb 2003 20:59:38 +0000 (20:59 +0000)
committerJaroslav Kysela <perex@perex.cz>
Wed, 12 Feb 2003 20:59:38 +0000 (20:59 +0000)
src/hwdep/hwdep.c
src/pcm/Makefile.am
src/pcm/pcm_jack.c [new file with mode: 0644]
src/pcm/pcm_symbols.c

index c828592669a250e016f3349ba4dd557db4a4d4c6..c47939ea547fcd00b0ddc915bde23571729a84a0 100644 (file)
@@ -52,7 +52,7 @@ static int snd_hwdep_open_conf(snd_hwdep_t **hwdep,
 #ifndef PIC
        extern void *snd_hwdep_open_symbols(void);
 #endif
-       void *h;
+       void *h = NULL;
        if (snd_config_get_type(hwdep_conf) != SND_CONFIG_TYPE_COMPOUND) {
                if (name)
                        SNDERR("Invalid type for HWDEP %s definition", name);
index d83cb33a4cc9f2284968053441fdad499ac976a8..da570be3cd72003079383bddc3b6c6961b17a85a 100644 (file)
@@ -1,6 +1,11 @@
-
 EXTRA_LTLIBRARIES = libpcm.la
 
+if HAVE_JACK
+JACK_PLUGIN = pcm_jack.c
+else !HAVE_JACK
+JACK_PLUGIN =
+endif !HAVE_JACK
+
 libpcm_la_SOURCES = atomic.c mask.c interval.c \
                    pcm.c pcm_params.c \
                    pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
@@ -8,7 +13,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_dmix.c pcm_symbols.c
+                   pcm_dmix.c pcm_symbols.c $(JACK_PLUGIN)
 noinst_HEADERS = pcm_local.h pcm_plugin.h mask.h mask_inline.h \
                 interval.h interval_inline.h plugin_ops.h ladspa.h
 
diff --git a/src/pcm/pcm_jack.c b/src/pcm/pcm_jack.c
new file mode 100644 (file)
index 0000000..f0c44ef
--- /dev/null
@@ -0,0 +1,565 @@
+/**
+ * \file pcm/pcm_jack.c
+ * \ingroup PCM_Plugins
+ * \brief PCM Jack Plugin Interface
+ * \author Maarten de Boer <mdeboer@iua.upf.es>
+ * \date 2003
+ */
+/*
+ *  PCM - File plugin
+ *  Copyright (c) 2003 by Maarten de Boer <mdeboer@iua.upf.es>
+ *
+ *
+ *   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
+ *
+ */
+
+#ifdef HAVE_JACK
+#define USE_JACK
+#endif
+
+#include <byteswap.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "pcm_local.h"
+#ifdef USE_JACK
+#include <jack/jack.h>
+#endif
+
+#ifndef PIC
+/* entry for static linking */
+const char *_snd_module_pcm_jack = "";
+#endif
+
+#ifndef DOC_HIDDEN
+
+typedef enum _jack_format {
+       SND_PCM_JACK_FORMAT_RAW
+} snd_pcm_jack_format_t;
+
+typedef struct {
+       char *fname;
+       int fd;
+       int format;
+       snd_timestamp_t trigger_tstamp;
+       snd_pcm_state_t state;
+       snd_pcm_uframes_t appl_ptr;
+       snd_pcm_uframes_t hw_ptr;
+
+#ifdef USE_JACK
+       jack_port_t **ports;
+       jack_client_t *client;
+#endif
+} snd_pcm_jack_t;
+
+#endif /* DOC_HIDDEN */
+
+static int snd_pcm_jack_close(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       int err = 0;
+
+       printf("snd_pcm_jack_close\n"); fflush(stdout);
+#ifdef USE_JACK
+       if (jack->client)
+               jack_client_close(jack->client);
+#endif
+       free(jack);
+       return err;
+}
+
+static int snd_pcm_jack_nonblock(snd_pcm_t *pcm, int nonblock)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_nonblock\n"); fflush(stdout);
+       return 0;
+}
+
+static int snd_pcm_jack_async(snd_pcm_t *pcm, int sig, pid_t pid)
+{
+       printf("snd_pcm_jack_async\n"); fflush(stdout);
+       return -ENOSYS;
+}
+
+static int snd_pcm_jack_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       unsigned short events;
+       char buf[1];
+       
+       printf("snd_pcm_jack_poll_revents\n"); fflush(stdout);
+       
+       assert(pfds && nfds == 1 && revents);
+
+       read(pfds[0].fd, buf, 1);
+
+       *revents = pfds[0].revents;
+       return 0;
+}
+
+static int snd_pcm_jack_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
+{
+       printf("snd_pcm_jack_info\n"); fflush(stdout);
+       memset(info, 0, sizeof(*info));
+       info->stream = pcm->stream;
+       info->card = -1;
+       strncpy(info->id, pcm->name, sizeof(info->id));
+       strncpy(info->name, pcm->name, sizeof(info->name));
+       strncpy(info->subname, pcm->name, sizeof(info->subname));
+       info->subdevices_count = 1;
+       return 0;
+}
+
+static int snd_pcm_jack_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_channel_info\n"); fflush(stdout);
+       return snd_pcm_channel_info_shm(pcm, info, -1);
+}
+
+static int snd_pcm_jack_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_status\n"); fflush(stdout);
+       memset(status, 0, sizeof(*status));
+       status->state = jack->state;
+       status->trigger_tstamp = jack->trigger_tstamp;
+       gettimeofday(&status->tstamp, 0);
+       status->avail = pcm->buffer_size;
+       status->avail_max = status->avail;
+       return 0;
+}
+
+static snd_pcm_state_t snd_pcm_jack_state(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_state\n"); fflush(stdout);
+       return jack->state;
+}
+
+static int snd_pcm_jack_hwsync(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       printf("snd_pcm_jack_hwsync\n"); fflush(stdout);
+       return 0;
+}
+
+static int snd_pcm_jack_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sframes_t *delayp)
+{
+       printf("snd_pcm_jack_delay\n"); fflush(stdout);
+       *delayp = snd_pcm_mmap_hw_avail(pcm);
+       return 0;
+}
+
+#ifdef USE_JACK
+int
+snd_pcm_jack_process_cb (jack_nframes_t nframes, snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       const snd_pcm_channel_area_t *areas;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_channel_area_t area;    
+       char buf[1];
+
+       area.addr = jack_port_get_buffer (jack->ports[0], nframes);
+       area.first = 0;
+       area.step = pcm->sample_bits;
+       
+       areas = snd_pcm_mmap_areas(pcm);
+       
+       while (xfer < nframes)
+       {
+               snd_pcm_uframes_t frames = nframes - xfer;
+               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
+               
+               if (cont < frames)
+                       frames = cont;
+
+               printf("snd_pcm_jack_process_cb hw=%d=%d + nframes=%d / frames=%d / bufsize=%d\n",
+                       offset,jack->hw_ptr,nframes,frames,pcm->buffer_size); fflush(stdout);
+
+               snd_pcm_area_copy(&area, xfer, &areas[0], offset, frames, pcm->format);
+               
+               snd_pcm_mmap_hw_forward(pcm,frames);
+               xfer += frames;
+       }
+       write(jack->fd,buf,1); /* for polling */
+
+       printf("jack_process = %d\n",snd_pcm_mmap_hw_offset(pcm)); fflush(stdout);
+       
+       return 0;      
+}
+#endif
+
+static int snd_pcm_jack_prepare(snd_pcm_t *pcm)
+{
+       int i;
+       
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_prepare\n"); fflush(stdout);
+       jack->state = SND_PCM_STATE_PREPARED;
+       *pcm->appl.ptr = 0;
+       *pcm->hw.ptr = 0;
+
+       jack->appl_ptr = jack->hw_ptr = 0;
+
+#ifdef USE_JACK
+       jack->ports = calloc (pcm->channels, sizeof(jack_port_t*));
+       for (i = 0; i < pcm->channels; i++)
+       {
+               char port_name[32];
+               sprintf(port_name,"chn%03d\n",i);
+               jack->ports[i] = jack_port_register (
+                       jack->client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+       }
+
+       jack_set_process_callback (jack->client,
+               (JackProcessCallback)snd_pcm_jack_process_cb, pcm);
+       jack_activate (jack->client);
+
+       for (i = 0; i < pcm->channels; i++)
+       {
+               if (jack_connect (jack->client, jack_port_name (jack->ports[i]), "alsa_pcm:playback_1"))
+               {
+                       fprintf (stderr, "cannot connect output ports\n");
+                       exit(-1);
+               }else{
+                       printf("connected %s to alsa_pcm:playback_1",jack_port_name(jack->ports[i]));
+               }
+       }
+#endif
+
+       return 0;
+}
+
+static int snd_pcm_jack_reset(snd_pcm_t *pcm)
+{
+       printf("snd_pcm_jack_reset\n"); fflush(stdout);
+       *pcm->appl.ptr = 0;
+       *pcm->hw.ptr = 0;
+       return 0;
+}
+
+static int snd_pcm_jack_start(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       assert(jack->state == SND_PCM_STATE_PREPARED);
+
+       printf("snd_pcm_jack_start\n"); fflush(stdout);
+       
+       jack->state = SND_PCM_STATE_RUNNING;
+
+       return 0;
+}
+
+static int snd_pcm_jack_drop(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_drop\n"); fflush(stdout);
+       assert(jack->state != SND_PCM_STATE_OPEN);
+       jack->state = SND_PCM_STATE_SETUP;
+       return 0;
+}
+
+static int snd_pcm_jack_drain(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_drain\n"); fflush(stdout);
+       assert(jack->state != SND_PCM_STATE_OPEN);
+       jack->state = SND_PCM_STATE_SETUP;
+       return 0;
+}
+
+static int snd_pcm_jack_pause(snd_pcm_t *pcm, int enable)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_pause\n"); fflush(stdout);
+       if (enable) {
+               if (jack->state != SND_PCM_STATE_RUNNING)
+                       return -EBADFD;
+       } else if (jack->state != SND_PCM_STATE_PAUSED)
+               return -EBADFD;
+       jack->state = SND_PCM_STATE_PAUSED;
+       return 0;
+}
+
+static snd_pcm_sframes_t snd_pcm_jack_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, frames);
+       snd_pcm_sframes_t ptr;
+       printf("snd_pcm_jack_rewind\n"); fflush(stdout);
+       return n;
+}
+
+static int snd_pcm_jack_resume(snd_pcm_t *pcm)
+{
+       return 0;
+}
+
+static snd_pcm_sframes_t snd_pcm_jack_mmap_commit(snd_pcm_t *pcm,
+                                                 snd_pcm_uframes_t offset,
+                                                 snd_pcm_uframes_t size)
+{
+       snd_pcm_mmap_appl_forward(pcm, size);
+       return size;
+}
+
+static snd_pcm_sframes_t snd_pcm_jack_avail_update(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       int ret = snd_pcm_mmap_avail(pcm);
+       printf("snd_pcm_jack_avail_update appl=%d hw=%d ret=%d\n",jack->appl_ptr,jack->hw_ptr,ret); fflush(stdout);
+       return ret;
+}
+
+static inline snd_mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
+                                       snd_pcm_hw_param_t var)
+{
+       return &params->masks[var - SND_PCM_HW_PARAM_FIRST_MASK];
+}
+
+static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
+                                               snd_pcm_hw_param_t var)
+{
+       return &params->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
+}
+
+static int snd_pcm_jack_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+       int err;
+       snd_pcm_jack_t *jack = pcm->private_data;
+
+       static snd_mask_t access = { .bits = { 
+                                       (1<<SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) |
+                                       (1<<SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) |
+                                       (1<<SNDRV_PCM_ACCESS_RW_INTERLEAVED) |
+                                       (1<<SNDRV_PCM_ACCESS_RW_NONINTERLEAVED),
+                                       0, 0, 0 } };
+
+       snd_interval_t t;
+
+       snd_pcm_format_mask_t format_mask = { SND_PCM_FMTBIT_FLOAT };
+       printf("snd_pcm_jack_hw_refine\n"); fflush(stdout);
+
+       t.openmin = 0;
+       t.openmax = 0;
+       t.empty = 0;
+       t.integer = 1;
+       t.min = 44100; /* TODO: get this value from jack */
+       t.max = 44100; /* TODO: get this value from jack */
+
+       snd_mask_refine(hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS), &access);
+
+       snd_mask_refine(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT),
+               &format_mask);
+       /*** this should work, right? */
+       /* snd_interval_refine(hw_param_interval(params,SND_PCM_HW_PARAM_RATE),&t);
+       */
+       /*** but it doesn't... the following does... ***/
+       err = _snd_pcm_hw_param_set_minmax(params, SND_PCM_HW_PARAM_RATE,
+                                          44100, 0, 
+                                          44100, 1);
+                                                
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+static int snd_pcm_jack_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       int err;
+       
+       printf("snd_pcm_jack_hw_params\n"); fflush(stdout);
+
+       return 0;
+}
+
+static int snd_pcm_jack_hw_free(snd_pcm_t *pcm)
+{
+       printf("snd_pcm_jack_hw_free\n"); fflush(stdout);
+       return 0;
+}
+
+static int snd_pcm_jack_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
+{
+       printf("snd_pcm_jack_sw_params\n"); fflush(stdout);
+       return 0;
+}
+
+static int snd_pcm_jack_mmap(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       printf("snd_pcm_jack_mmap\n"); fflush(stdout);
+
+       return 0;
+}
+
+static int snd_pcm_jack_munmap(snd_pcm_t *pcm)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       return 0;
+}
+
+static void snd_pcm_jack_dump(snd_pcm_t *pcm, snd_output_t *out)
+{
+       snd_pcm_jack_t *jack = pcm->private_data;
+       snd_output_printf(out, "Jack PCM\n", jack->fname);
+       if (pcm->setup) {
+               snd_output_printf(out, "Its setup is:\n");
+               snd_pcm_dump_setup(pcm, out);
+       }
+}
+
+static snd_pcm_ops_t snd_pcm_jack_ops = {
+       close: snd_pcm_jack_close,
+       info: snd_pcm_jack_info,
+       hw_refine: snd_pcm_jack_hw_refine,
+       hw_params: snd_pcm_jack_hw_params,
+       hw_free: snd_pcm_jack_hw_free,
+       sw_params: snd_pcm_jack_sw_params,
+       channel_info: snd_pcm_jack_channel_info,
+       dump: snd_pcm_jack_dump,
+       nonblock: snd_pcm_jack_nonblock,
+       async: snd_pcm_jack_async,
+       poll_revents: snd_pcm_jack_poll_revents,
+       mmap: snd_pcm_jack_mmap,
+       munmap: snd_pcm_jack_munmap,
+};
+
+static snd_pcm_fast_ops_t snd_pcm_jack_fast_ops = {
+       status: snd_pcm_jack_status,
+       state: snd_pcm_jack_state,
+       hwsync: snd_pcm_jack_hwsync,
+       delay: snd_pcm_jack_delay,
+       prepare: snd_pcm_jack_prepare,
+       reset: snd_pcm_jack_reset,
+       start: snd_pcm_jack_start,
+       drop: snd_pcm_jack_drop,
+       drain: snd_pcm_jack_drain,
+       pause: snd_pcm_jack_pause,
+       rewind: snd_pcm_jack_rewind,
+       resume: snd_pcm_jack_resume,
+       writei: snd_pcm_mmap_writei,
+       writen: snd_pcm_mmap_writen,
+       readi: snd_pcm_mmap_readi,
+       readn: snd_pcm_mmap_readn,
+       avail_update: snd_pcm_jack_avail_update,
+       mmap_commit: snd_pcm_jack_mmap_commit,
+};
+
+/**
+ * \brief Creates a new jack PCM
+ * \param pcmp Returns created PCM handle
+ * \param name Name of PCM
+ * \param stream Stream type
+ * \param mode Stream 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_jack_open(snd_pcm_t **pcmp, const char *name,
+       snd_pcm_stream_t stream, int mode)
+{
+       snd_pcm_t *pcm;
+       snd_pcm_jack_t *jack;
+       int err;
+       int fd[2];
+       
+       assert(pcmp);
+       printf("snd_pcm_jack_open\n"); fflush(stdout);
+       if (stream == SND_PCM_STREAM_PLAYBACK) {
+       } else {
+       }
+       jack = calloc(1, sizeof(snd_pcm_jack_t));
+       if (!jack) {
+               return -ENOMEM;
+       }
+
+#ifdef USE_JACK
+       jack->client = jack_client_new("alsa");
+       if (jack->client==0)
+               return -ENOENT; 
+#endif
+
+       jack->state = SND_PCM_STATE_OPEN;
+
+       err = snd_pcm_new(&pcm, SND_PCM_TYPE_JACK, name, stream, mode);
+       
+       if (err < 0) {
+               free(jack);
+               return err;
+       }
+       pcm->ops = &snd_pcm_jack_ops;
+       pcm->fast_ops = &snd_pcm_jack_fast_ops;
+       pcm->private_data = jack;
+
+       pcm->mmap_rw = 1;
+
+       socketpair(AF_LOCAL, SOCK_STREAM, 0, fd);
+       
+       jack->fd = fd[0];
+       pcm->poll_fd = fd[1];
+
+       snd_pcm_set_hw_ptr(pcm, &jack->hw_ptr, -1, 0);
+       snd_pcm_set_appl_ptr(pcm, &jack->appl_ptr, -1, 0);
+       *pcmp = pcm;
+
+       return 0;
+}
+
+/*! \page pcm_plugins
+
+\section pcm_plugins_jack Plugin: Jack
+
+*/
+
+/**
+ * \brief Creates a new Jack PCM
+ * \param pcmp Returns created PCM handle
+ * \param name Name of PCM
+ * \param root Root configuration node
+ * \param conf Configuration node with Jack PCM description
+ * \param stream Stream type
+ * \param mode Stream 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_jack_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)
+{
+       snd_config_iterator_t i, next;
+       snd_config_for_each(i, next, conf) {
+               snd_config_t *n = snd_config_iterator_entry(i);
+               const char *id;
+               if (snd_config_get_id(n, &id) < 0)
+                       continue;
+               if (snd_pcm_conf_generic_id(id))
+                       continue;
+               SNDERR("Unknown field %s", id);
+               return -EINVAL;
+       }
+       return snd_pcm_jack_open(pcmp, name, stream, mode);
+}
+#ifndef DOC_HIDDEN
+SND_DLSYM_BUILD_VERSION(_snd_pcm_jack_open, SND_PCM_DLSYM_VERSION);
+#endif
index e18880d8540d2d9326599b71cfae6975d0b3ab72..089077bbd1b2930ee989e322aad9497dfb3decc0 100644 (file)
@@ -39,6 +39,7 @@ extern const char *_snd_module_pcm_shm;
 extern const char *_snd_module_pcm_lfloat;
 extern const char *_snd_module_pcm_ladspa;
 extern const char *_snd_module_pcm_dmix;
+extern const char *_snd_module_pcm_jack;
 
 static const char **snd_pcm_open_objects[] = {
        &_snd_module_pcm_adpcm,
@@ -59,7 +60,8 @@ static const char **snd_pcm_open_objects[] = {
        &_snd_module_pcm_shm,
        &_snd_module_pcm_lfloat,
        &_snd_module_pcm_ladspa,
-       &_snd_module_pcm_dmix
+       &_snd_module_pcm_dmix,
+       &_snd_module_pcm_jack
 };
        
 void *snd_pcm_open_symbols(void)