mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-03 09:01:52 -05:00
Added multithread aware status for plugins
This commit is contained in:
parent
3196ef28ae
commit
a02e742609
7 changed files with 197 additions and 21 deletions
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
EXTRA_LTLIBRARIES = libpcm.la
|
EXTRA_LTLIBRARIES = libpcm.la
|
||||||
|
|
||||||
libpcm_la_SOURCES = mask.c interval.c \
|
libpcm_la_SOURCES = atomic.c mask.c interval.c \
|
||||||
pcm.c pcm_m4.c pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
|
pcm.c pcm_m4.c pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
|
||||||
pcm_route.c pcm_mulaw.c pcm_alaw.c pcm_adpcm.c \
|
pcm_route.c pcm_mulaw.c pcm_alaw.c pcm_adpcm.c \
|
||||||
pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
|
pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
|
||||||
pcm_shm.c pcm_file.c pcm_share.c pcm_null.c \
|
pcm_shm.c pcm_file.c pcm_share.c pcm_null.c \
|
||||||
pcm_params.c
|
pcm_params.c
|
||||||
noinst_HEADERS = pcm_local.h pcm_plugin.h mask.h mask_inline.h \
|
noinst_HEADERS = atomic.h pcm_local.h pcm_plugin.h mask.h mask_inline.h \
|
||||||
interval.h interval_inline.h plugin_ops.h
|
interval.h interval_inline.h plugin_ops.h
|
||||||
|
|
||||||
all: libpcm.la
|
all: libpcm.la
|
||||||
|
|
|
||||||
43
src/pcm/atomic.c
Normal file
43
src/pcm/atomic.c
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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 Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include "atomic.h"
|
||||||
|
|
||||||
|
void snd_atomic_read_wait(snd_atomic_read_t *t)
|
||||||
|
{
|
||||||
|
volatile const snd_atomic_write_t *w = t->write;
|
||||||
|
unsigned int loops = 0;
|
||||||
|
struct timespec ts;
|
||||||
|
while (w->begin != w->end) {
|
||||||
|
if (loops < MAX_SPIN_COUNT) {
|
||||||
|
sched_yield();
|
||||||
|
loops++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
loops = 0;
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = SPIN_SLEEP_DURATION;
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
85
src/pcm/atomic.h
Normal file
85
src/pcm/atomic.h
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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 Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/system.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@ static int snd_pcm_hw_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
|
||||||
snd_pcm_hw_t *hw = pcm->private_data;
|
snd_pcm_hw_t *hw = pcm->private_data;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SNDRV_PCM_IOCTL_DELAY, delayp) < 0) {
|
if (ioctl(fd, SNDRV_PCM_IOCTL_DELAY, delayp) < 0) {
|
||||||
SYSERR("SNDRV_PCM_IOCTL_DELAY failed");
|
// SYSERR("SNDRV_PCM_IOCTL_DELAY failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
#define _snd_pcm_access_mask _snd_mask
|
#define _snd_pcm_access_mask _snd_mask
|
||||||
#define _snd_pcm_format_mask _snd_mask
|
#define _snd_pcm_format_mask _snd_mask
|
||||||
|
|
@ -486,3 +487,4 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int orde
|
||||||
#define SND_PCM_ACCBIT_MMAP ((1 << (unsigned long) SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
#define SND_PCM_ACCBIT_MMAP ((1 << (unsigned long) SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
|
||||||
(1 << (unsigned long) SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
|
(1 << (unsigned long) SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
|
||||||
(1 << (unsigned long) SND_PCM_ACCESS_MMAP_COMPLEX))
|
(1 << (unsigned long) SND_PCM_ACCESS_MMAP_COMPLEX))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,18 +70,6 @@ int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
|
||||||
return snd_pcm_channel_info_shm(pcm, info, plugin->shmid);
|
return snd_pcm_channel_info_shm(pcm, info, plugin->shmid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
|
||||||
{
|
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
|
||||||
int err = snd_pcm_status(plugin->slave, status);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
status->avail = snd_pcm_mmap_avail(pcm);
|
|
||||||
if (plugin->client_frames)
|
|
||||||
status->avail_max = plugin->client_frames(pcm, status->avail_max);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
snd_pcm_state_t snd_pcm_plugin_state(snd_pcm_t *pcm)
|
snd_pcm_state_t snd_pcm_plugin_state(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
|
|
@ -104,11 +92,16 @@ int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
|
||||||
int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
|
int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
int err = snd_pcm_prepare(plugin->slave);
|
int err;
|
||||||
if (err < 0)
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
|
err = snd_pcm_prepare(plugin->slave);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
plugin->hw_ptr = 0;
|
plugin->hw_ptr = 0;
|
||||||
plugin->appl_ptr = 0;
|
plugin->appl_ptr = 0;
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
if (plugin->init) {
|
if (plugin->init) {
|
||||||
err = plugin->init(pcm);
|
err = plugin->init(pcm);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
@ -120,11 +113,16 @@ int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
|
||||||
int snd_pcm_plugin_reset(snd_pcm_t *pcm)
|
int snd_pcm_plugin_reset(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
int err = snd_pcm_reset(plugin->slave);
|
int err;
|
||||||
if (err < 0)
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
|
err = snd_pcm_reset(plugin->slave);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
plugin->hw_ptr = 0;
|
plugin->hw_ptr = 0;
|
||||||
plugin->appl_ptr = 0;
|
plugin->appl_ptr = 0;
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
if (plugin->init) {
|
if (plugin->init) {
|
||||||
err = plugin->init(pcm);
|
err = plugin->init(pcm);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
@ -172,19 +170,24 @@ snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames
|
||||||
/* FIXME: rate plugin */
|
/* FIXME: rate plugin */
|
||||||
if (plugin->slave_frames)
|
if (plugin->slave_frames)
|
||||||
frames = plugin->slave_frames(pcm, frames);
|
frames = plugin->slave_frames(pcm, frames);
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
err = snd_pcm_rewind(plugin->slave, frames);
|
err = snd_pcm_rewind(plugin->slave, frames);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
if (n <= 0)
|
if (n <= 0) {
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
if (plugin->client_frames)
|
if (plugin->client_frames)
|
||||||
err = plugin->client_frames(pcm, err);
|
err = plugin->client_frames(pcm, err);
|
||||||
snd_pcm_mmap_hw_backward(pcm, err);
|
snd_pcm_mmap_hw_backward(pcm, err);
|
||||||
n += err;
|
n += err;
|
||||||
}
|
} else
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
_end:
|
_end:
|
||||||
snd_pcm_mmap_appl_backward(pcm, n);
|
snd_pcm_mmap_appl_backward(pcm, n);
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,9 +210,11 @@ snd_pcm_uframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||||
frames = plugin->write(pcm, areas, offset, frames,
|
frames = plugin->write(pcm, areas, offset, frames,
|
||||||
slave_areas, slave_offset, &slave_frames);
|
slave_areas, slave_offset, &slave_frames);
|
||||||
assert(slave_frames <= snd_pcm_mmap_playback_avail(slave));
|
assert(slave_frames <= snd_pcm_mmap_playback_avail(slave));
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
snd_pcm_mmap_appl_forward(pcm, frames);
|
snd_pcm_mmap_appl_forward(pcm, frames);
|
||||||
snd_pcm_mmap_hw_forward(pcm, frames);
|
snd_pcm_mmap_hw_forward(pcm, frames);
|
||||||
snd_pcm_mmap_forward(slave, slave_frames);
|
snd_pcm_mmap_forward(slave, slave_frames);
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
offset += frames;
|
offset += frames;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
if (slave_frames == slave_cont)
|
if (slave_frames == slave_cont)
|
||||||
|
|
@ -239,9 +244,11 @@ snd_pcm_uframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||||
frames = plugin->read(pcm, areas, offset, frames,
|
frames = plugin->read(pcm, areas, offset, frames,
|
||||||
slave_areas, slave_offset, &slave_frames);
|
slave_areas, slave_offset, &slave_frames);
|
||||||
assert(slave_frames <= snd_pcm_mmap_capture_avail(slave));
|
assert(slave_frames <= snd_pcm_mmap_capture_avail(slave));
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
snd_pcm_mmap_appl_forward(pcm, frames);
|
snd_pcm_mmap_appl_forward(pcm, frames);
|
||||||
snd_pcm_mmap_hw_forward(pcm, frames);
|
snd_pcm_mmap_hw_forward(pcm, frames);
|
||||||
snd_pcm_mmap_forward(slave, slave_frames);
|
snd_pcm_mmap_forward(slave, slave_frames);
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
offset += frames;
|
offset += frames;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
if (slave_frames == slave_cont)
|
if (slave_frames == slave_cont)
|
||||||
|
|
@ -293,7 +300,9 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
|
||||||
snd_pcm_uframes_t xfer, offset;
|
snd_pcm_uframes_t xfer, offset;
|
||||||
snd_pcm_uframes_t slave_offset, slave_size;
|
snd_pcm_uframes_t slave_offset, slave_size;
|
||||||
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
|
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
snd_pcm_mmap_appl_forward(pcm, size);
|
snd_pcm_mmap_appl_forward(pcm, size);
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
slave_size = snd_pcm_avail_update(slave);
|
slave_size = snd_pcm_avail_update(slave);
|
||||||
|
|
@ -315,9 +324,11 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
|
||||||
slave_frames = slave_cont;
|
slave_frames = slave_cont;
|
||||||
frames = plugin->write(pcm, areas, offset, frames,
|
frames = plugin->write(pcm, areas, offset, frames,
|
||||||
slave_areas, slave_offset, &slave_frames);
|
slave_areas, slave_offset, &slave_frames);
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
snd_pcm_mmap_appl_forward(pcm, frames);
|
snd_pcm_mmap_appl_forward(pcm, frames);
|
||||||
snd_pcm_mmap_hw_forward(pcm, frames);
|
snd_pcm_mmap_hw_forward(pcm, frames);
|
||||||
snd_pcm_mmap_forward(slave, slave_frames);
|
snd_pcm_mmap_forward(slave, slave_frames);
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
xfer += frames;
|
xfer += frames;
|
||||||
if (frames == cont)
|
if (frames == cont)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
@ -365,8 +376,10 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||||
slave_frames = slave_cont;
|
slave_frames = slave_cont;
|
||||||
frames = plugin->read(pcm, areas, offset, frames,
|
frames = plugin->read(pcm, areas, offset, frames,
|
||||||
slave_areas, slave_offset, &slave_frames);
|
slave_areas, slave_offset, &slave_frames);
|
||||||
|
snd_atomic_write_begin(&plugin->watom);
|
||||||
snd_pcm_mmap_hw_forward(pcm, frames);
|
snd_pcm_mmap_hw_forward(pcm, frames);
|
||||||
snd_pcm_mmap_forward(slave, slave_frames);
|
snd_pcm_mmap_forward(slave, slave_frames);
|
||||||
|
snd_atomic_write_end(&plugin->watom);
|
||||||
xfer += frames;
|
xfer += frames;
|
||||||
if (frames == cont)
|
if (frames == cont)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
@ -411,6 +424,36 @@ int snd_pcm_plugin_poll_descriptor(snd_pcm_t *pcm)
|
||||||
return _snd_pcm_poll_descriptor(plugin->slave);
|
return _snd_pcm_poll_descriptor(plugin->slave);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||||
|
{
|
||||||
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
|
snd_pcm_sframes_t err;
|
||||||
|
snd_atomic_read_t ratom;
|
||||||
|
snd_atomic_read_init(&ratom, &plugin->watom);
|
||||||
|
_again:
|
||||||
|
snd_atomic_read_begin(&ratom);
|
||||||
|
err = snd_pcm_status(plugin->slave, status);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_atomic_read_ok(&ratom);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
status->appl_ptr = plugin->appl_ptr;
|
||||||
|
status->hw_ptr = plugin->hw_ptr;
|
||||||
|
err = snd_pcm_plugin_avail_update(pcm);
|
||||||
|
if (err < 0)
|
||||||
|
status->avail = pcm->buffer_size;
|
||||||
|
else
|
||||||
|
status->avail = err;
|
||||||
|
snd_pcm_plugin_delay(pcm, &status->delay);
|
||||||
|
if (!snd_atomic_read_ok(&ratom)) {
|
||||||
|
snd_atomic_read_wait(&ratom);
|
||||||
|
goto _again;
|
||||||
|
}
|
||||||
|
if (plugin->client_frames)
|
||||||
|
status->avail_max = plugin->client_frames(pcm, status->avail_max);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "atomic.h"
|
||||||
|
|
||||||
typedef snd_pcm_uframes_t (*snd_pcm_slave_xfer_areas_func_t)
|
typedef snd_pcm_uframes_t (*snd_pcm_slave_xfer_areas_func_t)
|
||||||
(snd_pcm_t *pcm,
|
(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas,
|
const snd_pcm_channel_area_t *areas,
|
||||||
|
|
@ -38,6 +40,7 @@ typedef struct {
|
||||||
int (*init)(snd_pcm_t *pcm);
|
int (*init)(snd_pcm_t *pcm);
|
||||||
int shmid;
|
int shmid;
|
||||||
snd_pcm_uframes_t appl_ptr, hw_ptr;
|
snd_pcm_uframes_t appl_ptr, hw_ptr;
|
||||||
|
snd_atomic_write_t watom;
|
||||||
} snd_pcm_plugin_t;
|
} snd_pcm_plugin_t;
|
||||||
|
|
||||||
int snd_pcm_plugin_close(snd_pcm_t *pcm);
|
int snd_pcm_plugin_close(snd_pcm_t *pcm);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue