mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-01 22:58:49 -04:00
- added poll_ask callback to mangle avail_min (rate_plugin as example)
- added mangling of avail_min to rate_plugin - added poll_fd_count variable - FIXME: move poll_revents callback to fast_ops
This commit is contained in:
parent
81f8c76094
commit
7c201b510a
15 changed files with 132 additions and 13 deletions
|
|
@ -1230,7 +1230,15 @@ int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
|
|||
*/
|
||||
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
|
||||
{
|
||||
int err;
|
||||
|
||||
assert(pcm && pfds);
|
||||
if (pcm->fast_ops->poll_ask) {
|
||||
err = pcm->fast_ops->poll_ask(pcm->fast_op_arg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
assert(pcm->poll_fd >= 0);
|
||||
if (space >= 1 && pfds) {
|
||||
pfds->fd = pcm->poll_fd;
|
||||
pfds->events = pcm->poll_events | POLLERR | POLLNVAL;
|
||||
|
|
@ -1255,7 +1263,7 @@ int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsign
|
|||
{
|
||||
assert(pcm && pfds && revents);
|
||||
if (pcm->ops->poll_revents)
|
||||
return pcm->ops->poll_revents(pcm, pfds, nfds, revents);
|
||||
return pcm->ops->poll_revents(pcm->op_arg, pfds, nfds, revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
|
|
@ -2008,6 +2016,8 @@ int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
|
|||
pcm->name = strdup(name);
|
||||
pcm->stream = stream;
|
||||
pcm->mode = mode;
|
||||
pcm->poll_fd_count = 1;
|
||||
pcm->poll_fd = -1;
|
||||
pcm->op_arg = pcm;
|
||||
pcm->fast_op_arg = pcm;
|
||||
INIT_LIST_HEAD(&pcm->async_handlers);
|
||||
|
|
@ -2061,6 +2071,17 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
|
|||
err_poll = poll(&pfd, 1, timeout);
|
||||
if (err_poll < 0)
|
||||
return -errno;
|
||||
#if 0 /* very useful code to test poll related problems */
|
||||
{
|
||||
snd_pcm_sframes_t delay, avail_update;
|
||||
snd_pcm_hwsync(pcm);
|
||||
avail_update = snd_pcm_avail_update(pcm);
|
||||
if (avail_update < pcm->avail_min) {
|
||||
printf("*** snd_pcm_wait() FATAL ERROR!!!\n");
|
||||
printf("avail_min = %li, avail_update = %li\n", pcm->avail_min, avail_update);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
err = snd_pcm_poll_descriptors_revents(pcm, &pfd, 1, &revents);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -766,6 +766,7 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
|
|||
.rewind = snd_pcm_dmix_rewind,
|
||||
.forward = snd_pcm_dmix_forward,
|
||||
.resume = snd_pcm_dmix_resume,
|
||||
.poll_ask = NULL,
|
||||
.writei = snd_pcm_mmap_writei,
|
||||
.writen = snd_pcm_mmap_writen,
|
||||
.readi = snd_pcm_dmix_readi,
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
|
|||
.rewind = snd_pcm_dshare_rewind,
|
||||
.forward = snd_pcm_dshare_forward,
|
||||
.resume = snd_pcm_dshare_resume,
|
||||
.poll_ask = NULL,
|
||||
.writei = snd_pcm_mmap_writei,
|
||||
.writen = snd_pcm_mmap_writen,
|
||||
.readi = snd_pcm_dshare_readi,
|
||||
|
|
|
|||
|
|
@ -463,6 +463,7 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
|
|||
.rewind = snd_pcm_dsnoop_rewind,
|
||||
.forward = snd_pcm_dsnoop_forward,
|
||||
.resume = snd_pcm_dsnoop_resume,
|
||||
.poll_ask = NULL,
|
||||
.writei = snd_pcm_dsnoop_writei,
|
||||
.writen = snd_pcm_dsnoop_writen,
|
||||
.readi = snd_pcm_mmap_readi,
|
||||
|
|
|
|||
|
|
@ -273,6 +273,14 @@ static int snd_pcm_file_resume(snd_pcm_t *pcm)
|
|||
return snd_pcm_resume(file->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
if (file->slave->fast_ops->poll_ask)
|
||||
return file->slave->fast_ops->poll_ask(file->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
|
|
@ -467,6 +475,7 @@ static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
|
|||
.rewind = snd_pcm_file_rewind,
|
||||
.forward = snd_pcm_file_forward,
|
||||
.resume = snd_pcm_file_resume,
|
||||
.poll_ask = snd_pcm_file_poll_ask,
|
||||
.writei = snd_pcm_file_writei,
|
||||
.writen = snd_pcm_file_writen,
|
||||
.readi = snd_pcm_file_readi,
|
||||
|
|
|
|||
|
|
@ -182,6 +182,14 @@ static int snd_pcm_hooks_resume(snd_pcm_t *pcm)
|
|||
return snd_pcm_resume(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
if (h->slave->fast_ops->poll_ask)
|
||||
return h->slave->fast_ops->poll_ask(h->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
|
|
@ -315,6 +323,7 @@ static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
|
|||
.rewind = snd_pcm_hooks_rewind,
|
||||
.forward = snd_pcm_hooks_forward,
|
||||
.resume = snd_pcm_hooks_resume,
|
||||
.poll_ask = snd_pcm_hooks_poll_ask,
|
||||
.writei = snd_pcm_hooks_writei,
|
||||
.writen = snd_pcm_hooks_writen,
|
||||
.readi = snd_pcm_hooks_readi,
|
||||
|
|
|
|||
|
|
@ -872,6 +872,7 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
|
|||
.rewind = snd_pcm_hw_rewind,
|
||||
.forward = snd_pcm_hw_forward,
|
||||
.resume = snd_pcm_hw_resume,
|
||||
.poll_ask = NULL,
|
||||
.writei = snd_pcm_hw_writei,
|
||||
.writen = snd_pcm_hw_writen,
|
||||
.readi = snd_pcm_hw_readi,
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ typedef struct {
|
|||
int (*hwsync)(snd_pcm_t *pcm);
|
||||
int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
|
||||
int (*resume)(snd_pcm_t *pcm);
|
||||
int (*poll_ask)(snd_pcm_t *pcm);
|
||||
snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
|
||||
|
|
@ -165,6 +166,7 @@ struct _snd_pcm {
|
|||
snd_pcm_type_t type;
|
||||
snd_pcm_stream_t stream;
|
||||
int mode;
|
||||
int poll_fd_count;
|
||||
int poll_fd;
|
||||
unsigned short poll_events;
|
||||
int setup;
|
||||
|
|
|
|||
|
|
@ -411,6 +411,14 @@ static int snd_pcm_meter_resume(snd_pcm_t *pcm)
|
|||
return snd_pcm_resume(meter->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_meter_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_meter_t *meter = pcm->private_data;
|
||||
if (meter->slave->fast_ops->poll_ask)
|
||||
return meter->slave->fast_ops->poll_ask(meter->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_meter_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t offset,
|
||||
snd_pcm_uframes_t size)
|
||||
|
|
@ -619,6 +627,7 @@ static snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
|
|||
.rewind = snd_pcm_meter_rewind,
|
||||
.forward = snd_pcm_meter_forward,
|
||||
.resume = snd_pcm_meter_resume,
|
||||
.poll_ask = snd_pcm_meter_poll_ask,
|
||||
.writei = snd_pcm_mmap_writei,
|
||||
.writen = snd_pcm_mmap_writen,
|
||||
.readi = snd_pcm_mmap_readi,
|
||||
|
|
|
|||
|
|
@ -560,6 +560,23 @@ static int snd_pcm_multi_resume(snd_pcm_t *pcm)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_multi_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_multi_t *multi = pcm->private_data;
|
||||
snd_pcm_t *slave;
|
||||
int err = 0;
|
||||
unsigned int i;
|
||||
for (i = 0; i < multi->slaves_count; ++i) {
|
||||
slave = multi->slaves[i].pcm;
|
||||
if (slave->fast_ops->poll_ask == NULL)
|
||||
continue;
|
||||
err = slave->fast_ops->poll_ask(slave->fast_op_arg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_multi_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t offset,
|
||||
snd_pcm_uframes_t size)
|
||||
|
|
@ -646,6 +663,7 @@ static snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
|
|||
.rewind = snd_pcm_multi_rewind,
|
||||
.forward = snd_pcm_multi_forward,
|
||||
.resume = snd_pcm_multi_resume,
|
||||
.poll_ask = snd_pcm_multi_poll_ask,
|
||||
.avail_update = snd_pcm_multi_avail_update,
|
||||
.mmap_commit = snd_pcm_multi_mmap_commit,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ static snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
|
|||
.rewind = snd_pcm_null_rewind,
|
||||
.forward = snd_pcm_null_forward,
|
||||
.resume = snd_pcm_null_resume,
|
||||
.poll_ask = NULL,
|
||||
.writei = snd_pcm_null_writei,
|
||||
.writen = snd_pcm_null_writen,
|
||||
.readi = snd_pcm_null_readi,
|
||||
|
|
|
|||
|
|
@ -343,6 +343,14 @@ int snd_pcm_plugin_resume(snd_pcm_t *pcm)
|
|||
return snd_pcm_resume(plugin->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_plugin_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||
if (plugin->slave->fast_ops->poll_ask)
|
||||
return plugin->slave->fast_ops->poll_ask(plugin->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||
const snd_pcm_channel_area_t *areas,
|
||||
snd_pcm_uframes_t offset,
|
||||
|
|
@ -662,6 +670,7 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
|
|||
.rewind = snd_pcm_plugin_rewind,
|
||||
.forward = snd_pcm_plugin_forward,
|
||||
.resume = snd_pcm_plugin_resume,
|
||||
.poll_ask = snd_pcm_plugin_poll_ask,
|
||||
.writei = snd_pcm_plugin_writei,
|
||||
.writen = snd_pcm_plugin_writen,
|
||||
.readi = snd_pcm_plugin_readi,
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ typedef struct {
|
|||
int close_slave;
|
||||
snd_atomic_write_t watom;
|
||||
snd_pcm_uframes_t appl_ptr, hw_ptr;
|
||||
snd_pcm_uframes_t orig_avail_min;
|
||||
snd_pcm_sw_params_t sw_params;
|
||||
enum rate_type type;
|
||||
unsigned int get_idx;
|
||||
unsigned int put_idx;
|
||||
|
|
@ -556,10 +558,11 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
|||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
snd_pcm_t *slave = rate->slave;
|
||||
snd_pcm_sw_params_t sparams;
|
||||
snd_pcm_sw_params_t *sparams;
|
||||
snd_pcm_uframes_t boundary1, boundary2;
|
||||
|
||||
sparams = *params;
|
||||
rate->sw_params = *params;
|
||||
sparams = &rate->sw_params;
|
||||
if ((rate->pitch >= LINEAR_DIV ? 1 : 0) ^ (pcm->stream == SND_PCM_STREAM_CAPTURE ? 1 : 0)) {
|
||||
boundary1 = pcm->buffer_size;
|
||||
boundary2 = slave->buffer_size;
|
||||
|
|
@ -576,7 +579,7 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
|||
}
|
||||
}
|
||||
params->boundary = boundary1;
|
||||
sparams.boundary = boundary2;
|
||||
sparams->boundary = boundary2;
|
||||
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||
rate->pitch = (((u_int64_t)slave->period_size * LINEAR_DIV) + pcm->period_size - 1) / pcm->period_size;
|
||||
do {
|
||||
|
|
@ -624,17 +627,18 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
|||
} while (1);
|
||||
assert((snd_pcm_uframes_t)snd_pcm_rate_slave_frames(pcm, pcm->period_size - 1) == slave->period_size - 1);
|
||||
}
|
||||
recalc(pcm, &sparams.avail_min);
|
||||
recalc(pcm, &sparams.xfer_align);
|
||||
recalc(pcm, &sparams.start_threshold);
|
||||
if (sparams.stop_threshold >= sparams.boundary) {
|
||||
sparams.stop_threshold = sparams.boundary;
|
||||
recalc(pcm, &sparams->avail_min);
|
||||
rate->orig_avail_min = sparams->avail_min;
|
||||
recalc(pcm, &sparams->xfer_align);
|
||||
recalc(pcm, &sparams->start_threshold);
|
||||
if (sparams->stop_threshold >= sparams->boundary) {
|
||||
sparams->stop_threshold = sparams->boundary;
|
||||
} else {
|
||||
recalc(pcm, &sparams.stop_threshold);
|
||||
recalc(pcm, &sparams->stop_threshold);
|
||||
}
|
||||
recalc(pcm, &sparams.silence_threshold);
|
||||
recalc(pcm, &sparams.silence_size);
|
||||
return snd_pcm_sw_params(slave, &sparams);
|
||||
recalc(pcm, &sparams->silence_threshold);
|
||||
recalc(pcm, &sparams->silence_size);
|
||||
return snd_pcm_sw_params(slave, sparams);
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_init(snd_pcm_t *pcm)
|
||||
|
|
@ -913,6 +917,36 @@ static int snd_pcm_rate_resume(snd_pcm_t *pcm)
|
|||
return snd_pcm_resume(rate->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
snd_pcm_uframes_t avail_min;
|
||||
int err;
|
||||
|
||||
if (rate->slave->fast_ops->poll_ask) {
|
||||
err = rate->slave->fast_ops->poll_ask(rate->slave->fast_op_arg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
avail_min = rate->appl_ptr % pcm->period_size;
|
||||
if (avail_min > 0) {
|
||||
recalc(pcm, &avail_min);
|
||||
if (avail_min < rate->slave->buffer_size &&
|
||||
avail_min != rate->slave->period_size)
|
||||
avail_min++; /* 1st small little rounding correction */
|
||||
if (avail_min < rate->slave->buffer_size &&
|
||||
avail_min != rate->slave->period_size)
|
||||
avail_min++; /* 2nd small little rounding correction */
|
||||
avail_min += rate->orig_avail_min;
|
||||
} else {
|
||||
avail_min = rate->orig_avail_min;
|
||||
}
|
||||
if (rate->sw_params.avail_min == avail_min)
|
||||
return 0;
|
||||
rate->sw_params.avail_min = avail_min;
|
||||
return snd_pcm_sw_params(rate->slave, &rate->sw_params);
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t appl_offset)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
|
|
@ -1291,6 +1325,7 @@ static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
|
|||
.rewind = snd_pcm_rate_rewind,
|
||||
.forward = snd_pcm_rate_forward,
|
||||
.resume = snd_pcm_rate_resume,
|
||||
.poll_ask = snd_pcm_rate_poll_ask,
|
||||
.writei = snd_pcm_mmap_writei,
|
||||
.writen = snd_pcm_mmap_writen,
|
||||
.readi = snd_pcm_mmap_readi,
|
||||
|
|
|
|||
|
|
@ -1296,6 +1296,7 @@ static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
|
|||
.rewind = snd_pcm_share_rewind,
|
||||
.forward = snd_pcm_share_forward,
|
||||
.resume = snd_pcm_share_resume,
|
||||
.poll_ask = NULL, /* FIXME */
|
||||
.avail_update = snd_pcm_share_avail_update,
|
||||
.mmap_commit = snd_pcm_share_mmap_commit,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -602,6 +602,7 @@ static snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
|
|||
.rewind = snd_pcm_shm_rewind,
|
||||
.forward = snd_pcm_shm_forward,
|
||||
.resume = snd_pcm_shm_resume,
|
||||
.poll_ask = NULL,
|
||||
.writei = snd_pcm_mmap_writei,
|
||||
.writen = snd_pcm_mmap_writen,
|
||||
.readi = snd_pcm_mmap_readi,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue