ctrl->result = snd_pcm_mmap_forward(pcm, ctrl->u.mmap_forward.frames);
ctrl->appl_ptr = *pcm->appl_ptr;
break;
+ case SND_PCM_IOCTL_SET_AVAIL_MIN:
+ ctrl->result = snd_pcm_set_avail_min(pcm, ctrl->u.set_avail_min.frames);
+ break;
case SND_PCM_IOCTL_POLL_DESCRIPTOR:
ctrl->result = 0;
return shm_ack_fd(client, snd_pcm_poll_descriptor(pcm));
#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xfa)
#define SND_PCM_IOCTL_MMAP_INFO _IO ('A', 0xfb)
#define SND_PCM_IOCTL_POLL_DESCRIPTOR _IO ('A', 0xfc)
+#define SND_PCM_IOCTL_SET_AVAIL_MIN _IO ('A', 0xfd)
typedef struct {
long result;
struct {
ssize_t frames;
} mmap_forward;
+ struct {
+ ssize_t frames;
+ } set_avail_min;
} u;
char data[0];
} snd_pcm_shm_ctrl_t;
int snd_pcm_channels_mask(snd_pcm_t *pcm, bitset_t *cmask);
int snd_pcm_wait(snd_pcm_t *pcm, int timeout);
ssize_t snd_pcm_avail_update(snd_pcm_t *pcm);
+int snd_pcm_set_avail_min(snd_pcm_t *pcm, size_t size);
/* mmap */
return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
}
+int snd_pcm_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ int err;
+ assert(pcm);
+ assert(pcm->valid_setup);
+ assert(frames > 0 && frames < pcm->setup.buffer_size);
+ err = pcm->fast_ops->set_avail_min(pcm->fast_op_arg, frames);
+ if (err < 0)
+ return err;
+ pcm->setup.avail_min = frames;
+ return 0;
+}
+
ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
{
assert(pcm);
return snd_pcm_avail_update(file->slave);
}
+int snd_pcm_file_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ snd_pcm_file_t *file = pcm->private;
+ return snd_pcm_set_avail_min(file->slave, frames);
+}
+
static int snd_pcm_file_mmap(snd_pcm_t *pcm)
{
snd_pcm_file_t *file = pcm->private;
channels_mask: snd_pcm_file_channels_mask,
avail_update: snd_pcm_file_avail_update,
mmap_forward: snd_pcm_file_mmap_forward,
+ set_avail_min: snd_pcm_file_set_avail_min,
};
int snd_pcm_file_open(snd_pcm_t **pcmp, char *name, char *fname, int fd, snd_pcm_t *slave, int close_slave)
return avail;
}
+static int snd_pcm_hw_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ snd_pcm_hw_t *hw = pcm->private;
+ hw->mmap_control->avail_min = frames;
+ return 0;
+}
+
static int snd_pcm_hw_channels_mask(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
bitset_t *cmask ATTRIBUTE_UNUSED)
{
channels_mask: snd_pcm_hw_channels_mask,
avail_update: snd_pcm_hw_avail_update,
mmap_forward: snd_pcm_hw_mmap_forward,
+ set_avail_min: snd_pcm_hw_set_avail_min,
};
int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdevice, int stream, int mode)
int (*channels_mask)(snd_pcm_t *pcm, bitset_t *cmask);
ssize_t (*avail_update)(snd_pcm_t *pcm);
ssize_t (*mmap_forward)(snd_pcm_t *pcm, size_t size);
+ int (*set_avail_min)(snd_pcm_t *pcm, size_t frames);
} snd_pcm_fast_ops_t;
typedef struct {
return size;
}
+int snd_pcm_multi_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ snd_pcm_multi_t *multi = pcm->private;
+ return snd_pcm_set_avail_min(multi->slaves[0].pcm, frames);
+}
+
static int snd_pcm_multi_channels_mask(snd_pcm_t *pcm, bitset_t *cmask)
{
snd_pcm_multi_t *multi = pcm->private;
channels_mask: snd_pcm_multi_channels_mask,
avail_update: snd_pcm_multi_avail_update,
mmap_forward: snd_pcm_multi_mmap_forward,
+ set_avail_min: snd_pcm_multi_set_avail_min,
};
int snd_pcm_multi_open(snd_pcm_t **pcmp, char *name,
return err;
}
+int snd_pcm_plugin_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ snd_pcm_plugin_t *plugin = pcm->private;
+ snd_pcm_t *slave = plugin->slave;
+ return snd_pcm_set_avail_min(slave, frames);
+}
+
int snd_pcm_plugin_mmap(snd_pcm_t *pcm)
{
snd_pcm_plugin_t *plugin = pcm->private;
channels_mask: snd_pcm_plugin_channels_mask,
avail_update: snd_pcm_plugin_avail_update,
mmap_forward: snd_pcm_plugin_mmap_forward,
+ set_avail_min: snd_pcm_plugin_set_avail_min,
};
return ret;
}
+static int snd_pcm_share_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ snd_pcm_share_t *share = pcm->private;
+ snd_pcm_share_slave_t *slave = share->slave;
+ pthread_mutex_lock(&slave->mutex);
+ pcm->setup.avail_min = frames;
+ _snd_pcm_update_poll(pcm);
+ pthread_mutex_unlock(&slave->mutex);
+ return 0;
+}
+
static int snd_pcm_share_channels_mask(snd_pcm_t *pcm, bitset_t *cmask)
{
snd_pcm_share_t *share = pcm->private;
channels_mask: snd_pcm_share_channels_mask,
avail_update: snd_pcm_share_avail_update,
mmap_forward: snd_pcm_share_mmap_forward,
+ set_avail_min: snd_pcm_share_set_avail_min,
};
int snd_pcm_share_open(snd_pcm_t **pcmp, char *name, char *sname,
return snd_pcm_shm_action(pcm);
}
+static int snd_pcm_shm_set_avail_min(snd_pcm_t *pcm, size_t frames)
+{
+ snd_pcm_shm_t *shm = pcm->private;
+ volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
+ ctrl->cmd = SND_PCM_IOCTL_SET_AVAIL_MIN;
+ ctrl->u.set_avail_min.frames = frames;
+ return snd_pcm_shm_action(pcm);
+}
+
static int snd_pcm_shm_poll_descriptor(snd_pcm_t *pcm)
{
snd_pcm_shm_t *shm = pcm->private;
channels_mask: snd_pcm_shm_channels_mask,
avail_update: snd_pcm_shm_avail_update,
mmap_forward: snd_pcm_shm_mmap_forward,
+ set_avail_min: snd_pcm_shm_set_avail_min,
};
static int make_local_socket(const char *filename)