mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Added snd_timer_async() function.
More updates to pcm_dmix.c .
This commit is contained in:
parent
7c5e5f5728
commit
757785fece
5 changed files with 125 additions and 32 deletions
|
|
@ -48,6 +48,12 @@
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue