]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Added snd_timer_async() function.
authorJaroslav Kysela <perex@perex.cz>
Thu, 6 Feb 2003 19:15:53 +0000 (19:15 +0000)
committerJaroslav Kysela <perex@perex.cz>
Thu, 6 Feb 2003 19:15:53 +0000 (19:15 +0000)
More updates to pcm_dmix.c .

src/pcm/pcm_dmix.c
src/pcm/pcm_null.c
src/timer/timer.c
src/timer/timer_hw.c
src/timer/timer_local.h

index a19b19f1334d7eaaa190c0147d0ceaadb1fd717e..4ea253f142ff8ef988ebb288641b578d9dfdca74 100644 (file)
 const char *_snd_module_pcm_dmix = "";
 #endif
 
+/*
+ *
+ */
+int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
+
 /*
  *
  */
@@ -432,24 +438,51 @@ static int client_discard(snd_pcm_dmix_t *dmix)
        return 0;
 }
 
+/*
+ *  ring buffer operation
+ */
+
+/*
+ *  synchronize shm ring buffer with hardware
+ */
+static void snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+{
+       snd_pcm_dmix_t *dmix = pcm->private_data;
+       snd_pcm_uframes_t appl_ptr;
+       
+       /* get the start of update area */
+       appl_ptr = dmix->appl_ptr - size;
+       if (appl_ptr > pcm->boundary)
+               appl_ptr += pcm->boundary;
+}
+
 /*
  *  plugin implementation
  */
 
-static int snd_pcm_dmix_nonblock(snd_pcm_t *pcm, int nonblock)
+static int snd_pcm_dmix_nonblock(snd_pcm_t *pcm, int nonblock ATTRIBUTE_UNUSED)
 {
+       /* value is cached for us in pcm->mode (SND_PCM_NONBLOCK flag) */
        return 0;
 }
 
 static int snd_pcm_dmix_async(snd_pcm_t *pcm, int sig, pid_t pid)
 {
        snd_pcm_dmix_t *dmix = pcm->private_data;
-       return 0;
+       return snd_timer_async(dmix->timer, sig, pid);
 }
 
 static int snd_pcm_dmix_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
 {
        snd_pcm_dmix_t *dmix = pcm->private_data;
+       memset(info, 0, sizeof(*info));
+       info->stream = pcm->stream;
+       info->card = -1;
+       /* FIXME: fill this with something more useful: we know the hardware name */
+       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;
 }
 
@@ -499,26 +532,25 @@ static int snd_pcm_dmix_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 
 static int snd_pcm_dmix_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 {
-       snd_pcm_dmix_t *dmix = pcm->private_data;
+       // snd_pcm_dmix_t *dmix = pcm->private_data;
        return 0;
 }
 
 static int snd_pcm_dmix_hw_free(snd_pcm_t *pcm)
 {
-       snd_pcm_dmix_t *dmix = pcm->private_data;
+       // snd_pcm_dmix_t *dmix = pcm->private_data;
        return 0;
 }
 
 static int snd_pcm_dmix_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
-       snd_pcm_dmix_t *dmix = pcm->private_data;
+       // snd_pcm_dmix_t *dmix = pcm->private_data;
        return 0;
 }
 
 static int snd_pcm_dmix_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
 {
-       snd_pcm_dmix_t *dmix = pcm->private_data;
-       return 0;
+        return snd_pcm_channel_info_shm(pcm, info, -1);
 }
 
 static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
@@ -595,33 +627,35 @@ static int snd_pcm_dmix_resume(snd_pcm_t *pcm)
 
 static snd_pcm_sframes_t snd_pcm_dmix_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
-       return -ENODEV;
+       int res = snd_pcm_mmap_writei(pcm, buffer, size);
+       snd_pcm_dmix_sync_ptr(pcm, size);
+       return res;
 }
 
 static snd_pcm_sframes_t snd_pcm_dmix_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
-       return -ENODEV;
+       int res = snd_pcm_mmap_writen(pcm, bufs, size);
+       snd_pcm_dmix_sync_ptr(pcm, size);
+       return res;
 }
 
-static snd_pcm_sframes_t snd_pcm_dmix_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_dmix_readi(snd_pcm_t *pcm ATTRIBUTE_UNUSED, void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size ATTRIBUTE_UNUSED)
 {
        return -ENODEV;
 }
 
-static snd_pcm_sframes_t snd_pcm_dmix_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_dmix_readn(snd_pcm_t *pcm ATTRIBUTE_UNUSED, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size ATTRIBUTE_UNUSED)
 {
        return -ENODEV;
 }
 
-static int snd_pcm_dmix_mmap(snd_pcm_t *pcm)
+static int snd_pcm_dmix_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
-       snd_pcm_dmix_t *dmix = pcm->private_data;
        return 0;
 }
 
-static int snd_pcm_dmix_munmap(snd_pcm_t *pcm)
+static int snd_pcm_dmix_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
-       snd_pcm_dmix_t *dmix = pcm->private_data;
        return 0;
 }
 
@@ -648,16 +682,17 @@ static int snd_pcm_dmix_close(snd_pcm_t *pcm)
 }
 
 static snd_pcm_sframes_t snd_pcm_dmix_mmap_commit(snd_pcm_t *pcm,
-                                               snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
-                                               snd_pcm_uframes_t size)
+                                                 snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
+                                                 snd_pcm_uframes_t size)
 {
-       snd_pcm_dmix_t *hw = pcm->private_data;
-       return 0;
+       snd_pcm_mmap_appl_forward(pcm, size);
+       snd_pcm_dmix_sync_ptr(pcm, size);
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_dmix_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_dmix_avail_update(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
-       snd_pcm_dmix_t *hw = pcm->private_data;
+       //snd_pcm_dmix_t *dmix = pcm->private_data;
        return 0;
 }
 
index c52ded4f9ef09c9060ae4d3dab7e0630e1f9f3de..04202a6f974d637994d5a471ffd150bb5af3c0b7 100644 (file)
@@ -65,7 +65,7 @@ static int snd_pcm_null_async(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int sig ATTRIBUTE
        return -ENOSYS;
 }
 
-static int snd_pcm_null_info(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_info_t * info)
+static int snd_pcm_null_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
 {
        memset(info, 0, sizeof(*info));
        info->stream = pcm->stream;
@@ -79,7 +79,6 @@ static int snd_pcm_null_info(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_info_t * i
 
 static int snd_pcm_null_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
 {
-       snd_pcm_null_t *null = pcm->private_data;
        return snd_pcm_channel_info_shm(pcm, info, -1);
 }
 
index 2fc05bc8c28498bb3cd178f0ea523a1327861be0..6cada821bf1b1e8b8e96c6fe57557177cb8e6e0a 100644 (file)
@@ -73,6 +73,7 @@ This example shows opening a timer device and reading of timer events.
 #include <string.h>
 #include <fcntl.h>
 #include <dlfcn.h>
+#include <signal.h>
 #include <sys/ioctl.h>
 #include "timer_local.h"
 
@@ -350,6 +351,27 @@ int snd_timer_nonblock(snd_timer_t *timer, int nonblock)
        return 0;
 }
 
+#ifndef DOC_HIDDEN
+/**
+ * \brief set async mode
+ * \param timer timer handle
+ * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
+ * \param pid Process ID to signal: 0 current
+ * \return 0 on success otherwise a negative error code
+ *
+ * A signal is raised every period.
+ */
+int snd_timer(snd_timer_t *timer, int sig, pid_t pid)
+{
+       assert(timer);
+        if (sig == 0)
+                sig = SIGIO;
+       if (pid == 0)
+               pid = getpid();
+       return timer->ops->async(timer, sig, pid);
+}
+#endif
+
 /**
  * \brief get size of the snd_timer_info_t structure in bytes
  * \return size of the snd_timer_info_t structure in bytes
index 0fc540bd0f77f30fd40bfff1e07ed2e2b3446131..76651d898e809037d82cf318851404d36983053a 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#define __USE_GNU
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include "timer_local.h"
@@ -61,6 +62,38 @@ static int snd_timer_hw_nonblock(snd_timer_t *timer, int nonblock)
        return 0;
 }
 
+static int snd_timer_hw_async(snd_timer_t *timer, int sig, pid_t pid)
+{
+       long flags;
+       int fd;
+
+       assert(timer);
+       fd = timer->poll_fd;
+       if ((flags = fcntl(fd, F_GETFL)) < 0) {
+               SYSERR("F_GETFL failed");
+               return -errno;
+       }
+       if (sig >= 0)
+               flags |= O_ASYNC;
+       else
+               flags &= ~O_ASYNC;
+       if (fcntl(fd, F_SETFL, flags) < 0) {
+               SYSERR("F_SETFL for O_ASYNC failed");
+               return -errno;
+       }
+       if (sig < 0)
+               return 0;
+       if (fcntl(fd, F_SETSIG, (long)sig) < 0) {
+               SYSERR("F_SETSIG failed");
+               return -errno;
+       }
+       if (fcntl(fd, F_SETOWN, (long)pid) < 0) {
+               SYSERR("F_SETOWN failed");
+               return -errno;
+       }
+       return 0;
+}
+
 static int snd_timer_hw_info(snd_timer_t *handle, snd_timer_info_t * info)
 {
        snd_timer_t *tmr;
@@ -148,15 +181,16 @@ static ssize_t snd_timer_hw_read(snd_timer_t *handle, void *buffer, size_t size)
 }
 
 static snd_timer_ops_t snd_timer_hw_ops = {
-       close: snd_timer_hw_close,
-       nonblock: snd_timer_hw_nonblock,
-       info: snd_timer_hw_info,
-       params: snd_timer_hw_params,
-       status: snd_timer_hw_status,
-       rt_start: snd_timer_hw_start,
-       rt_stop: snd_timer_hw_stop,
-       rt_continue: snd_timer_hw_continue,
-       read: snd_timer_hw_read,
+       .close = snd_timer_hw_close,
+       .nonblock = snd_timer_hw_nonblock,
+       .async = snd_timer_hw_async,
+       .info = snd_timer_hw_info,
+       .params = snd_timer_hw_params,
+       .status = snd_timer_hw_status,
+       .rt_start = snd_timer_hw_start,
+       .rt_stop = snd_timer_hw_stop,
+       .rt_continue = snd_timer_hw_continue,
+       .read = snd_timer_hw_read,
 };
 
 int snd_timer_hw_open(snd_timer_t **handle, const char *name, int dev_class, int dev_sclass, int card, int device, int subdevice, int mode)
index 67aacf1be7c9fa8f5d76a8c27ae64e8121e1c7cd..8c3ad3d737ca36516118b07f20a1436efe753d12 100644 (file)
@@ -27,6 +27,7 @@
 typedef struct {
        int (*close)(snd_timer_t *timer);
        int (*nonblock)(snd_timer_t *timer, int nonblock);
+       int (*async)(snd_timer_t *timer, int sig, pid_t pid);
        int (*info)(snd_timer_t *timer, snd_timer_info_t *info);
        int (*params)(snd_timer_t *timer, snd_timer_params_t *params);
        int (*status)(snd_timer_t *timer, snd_timer_status_t *status);
@@ -62,3 +63,5 @@ struct _snd_timer_query {
 };
 
 int snd_timer_query_hw_open(snd_timer_query_t **handle, const char *name, int mode);
+
+int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);