Better PCM mmap API. Fixed pcm_multi

This commit is contained in:
Abramo Bagnara 2001-04-13 15:40:53 +00:00
parent c4f95f48c3
commit 6a3b962d06
16 changed files with 279 additions and 279 deletions

View file

@ -455,8 +455,10 @@ static int pcm_shm_cmd(client_t *client)
ctrl->result = snd_pcm_munmap(pcm);
break;
}
case SND_PCM_IOCTL_MMAP_FORWARD:
ctrl->result = snd_pcm_mmap_forward(pcm, ctrl->u.mmap_forward.frames);
case SND_PCM_IOCTL_MMAP_COMMIT:
ctrl->result = snd_pcm_mmap_commit(pcm,
ctrl->u.mmap_commit.offset,
ctrl->u.mmap_commit.frames);
ctrl->appl_ptr = *pcm->appl_ptr;
break;
case SND_PCM_IOCTL_POLL_DESCRIPTOR:
@ -610,7 +612,7 @@ static int ctl_shm_cmd(client_t *client)
ctrl->result = snd_ctl_pcm_next_device(ctl, &ctrl->u.device);
break;
case SND_CTL_IOCTL_PCM_SURROUND_NEXT_DEVICE:
ctrl->result = snd_ctl_pcm_surround_next_device(ctl, &ctrl->u.surround.type, &ctrl->u.surround.device);
ctrl->result = snd_ctl_pcm_surround_next_device(ctl, ctrl->u.surround.type, &ctrl->u.surround.device);
break;
case SNDRV_CTL_IOCTL_PCM_INFO:
ctrl->result = snd_ctl_pcm_info(ctl, &ctrl->u.pcm_info);

View file

@ -42,7 +42,7 @@ typedef enum _snd_transport_type {
#define SND_PCM_IOCTL_STATE _IO ('A', 0xf1)
#define SND_PCM_IOCTL_MMAP _IO ('A', 0xf2)
#define SND_PCM_IOCTL_MUNMAP _IO ('A', 0xf3)
#define SND_PCM_IOCTL_MMAP_FORWARD _IO ('A', 0xf4)
#define SND_PCM_IOCTL_MMAP_COMMIT _IO ('A', 0xf4)
#define SND_PCM_IOCTL_AVAIL_UPDATE _IO ('A', 0xf5)
#define SND_PCM_IOCTL_ASYNC _IO ('A', 0xf6)
#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xf7)
@ -77,8 +77,9 @@ typedef struct {
int fd;
} link;
struct {
snd_pcm_uframes_t offset;
snd_pcm_uframes_t frames;
} mmap_forward;
} mmap_commit;
} u;
char data[0];
} snd_pcm_shm_ctrl_t;
@ -101,7 +102,7 @@ typedef struct {
} async;
int device;
struct {
int type;
snd_pcm_surround_type_t type;
int device;
} surround;
int subscribe_events;

View file

@ -381,16 +381,12 @@ int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out);
int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out);
/* mmap */
const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm);
const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm);
const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
int snd_pcm_mmap_begin(snd_pcm_t *pcm,
const snd_pcm_channel_area_t **areas,
snd_pcm_uframes_t *offset,
snd_pcm_uframes_t *frames);
int snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
snd_pcm_uframes_t frames);
const char *snd_pcm_stream_name(snd_pcm_stream_t stream);
const char *snd_pcm_access_name(snd_pcm_access_t _access);

View file

@ -1098,23 +1098,6 @@ snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
return pcm->fast_ops->avail_update(pcm->fast_op_arg);
}
/**
* \brief Advance PCM frame position in mmap buffer
* \param pcm PCM handle
* \param size movement size
* \return a positive number of actual movement size otherwise a negative
* error code
*
* On playback does all the actions needed to transport the frames across
* underlying layers.
*/
snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
assert(size > 0);
assert(size <= snd_pcm_mmap_avail(pcm));
return pcm->fast_ops->mmap_forward(pcm->fast_op_arg, size);
}
/**
* \brief Silence an area
* \param dst_area area specification
@ -3932,64 +3915,57 @@ void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
obj->stream = snd_enum_to_int(val);
}
/**
* \brief Get channel areas for a given PCM when running
* \brief Application request to access a portion of mmap area
* \param pcm PCM handle
* \return pointer to channel areas (one for each channel)
* \param areas Returned mmap channel areas
* \param offset Returned mmap area offset
* \param size mmap area portion size (wanted on entry, contiguous
available on exit)
* \return 0 on success otherwise a negative error code
*/
const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm)
{
return pcm->running_areas;
}
/**
* \brief Get channel areas for a given PCM when stopped
* \param pcm PCM handle
* \return pointer to channel areas (one for each channel)
*/
const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm)
{
return pcm->stopped_areas;
}
/**
* \brief Get appropriate channel areas for a given PCM according to its state (running or stopped)
* \param pcm PCM handle
* \return pointer to channel areas (one for each channel)
*/
const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
int snd_pcm_mmap_begin(snd_pcm_t *pcm,
const snd_pcm_channel_area_t **areas,
snd_pcm_uframes_t *offset,
snd_pcm_uframes_t *frames)
{
snd_pcm_uframes_t cont;
snd_pcm_uframes_t avail;
snd_pcm_uframes_t f;
assert(pcm && areas && offset && frames);
if (pcm->stopped_areas &&
snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING)
return pcm->stopped_areas;
return pcm->running_areas;
}
/**
* \brief Correct frames count according to contiguity consideration inside PCM ring buffer
* \param pcm PCM handle
* \param frames Frames to transfer
* \return Number of contiguous frames transferrable
*/
snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
assert(pcm);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
return snd_pcm_mmap_playback_xfer(pcm, frames);
*areas = pcm->stopped_areas;
else
return snd_pcm_mmap_capture_xfer(pcm, frames);
*areas = pcm->running_areas;
*offset = *pcm->appl_ptr % pcm->buffer_size;
avail = snd_pcm_mmap_avail(pcm);
f = *frames;
if (f > avail)
f = avail;
cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
if (f > cont)
f = cont;
*frames = f;
return 0;
}
/**
* \brief Return application offset inside ring buffer
* \brief Application has completed the access to area requested with
#snd_pcm_mmap_begin
* \param pcm PCM handle
* \return Offset for frames transfer
* \return 0 on success otherwise a negative error code
*
* To call this with offset/frames values different from that returned
* by snd_pcm_mmap_begin has undefined effects and it has to be avoided.
*/
snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
int snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
snd_pcm_uframes_t frames)
{
assert(pcm);
return *pcm->appl_ptr % pcm->buffer_size;
assert(pcm);
assert(offset == *pcm->appl_ptr % pcm->buffer_size);
assert(frames <= snd_pcm_mmap_avail(pcm));
return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
}
#ifndef DOC_HIDDEN

View file

@ -268,26 +268,19 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
return n;
}
static snd_pcm_sframes_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
{
snd_pcm_file_t *file = pcm->private_data;
snd_pcm_uframes_t ofs = snd_pcm_mmap_offset(pcm);
snd_pcm_sframes_t n = snd_pcm_mmap_forward(file->slave, size);
snd_pcm_uframes_t xfer = 0;
if (n <= 0)
return n;
while (xfer < (snd_pcm_uframes_t)n) {
snd_pcm_uframes_t frames = n - xfer;
snd_pcm_uframes_t cont = pcm->buffer_size - ofs;
if (frames > cont)
frames = cont;
snd_pcm_file_add_frames(pcm, snd_pcm_mmap_areas(file->slave), ofs, frames);
ofs += frames;
if (ofs == pcm->buffer_size)
ofs = 0;
xfer += frames;
}
return n;
snd_pcm_uframes_t ofs;
snd_pcm_uframes_t siz = size;
const snd_pcm_channel_area_t *areas;
snd_pcm_mmap_begin(file->slave, &areas, &ofs, &siz);
assert(ofs == offset && siz == size);
snd_pcm_mmap_commit(file->slave, ofs, siz);
snd_pcm_file_add_frames(pcm, areas, ofs, siz);
return 0;
}
static snd_pcm_sframes_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
@ -400,7 +393,7 @@ snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
readi: snd_pcm_file_readi,
readn: snd_pcm_file_readn,
avail_update: snd_pcm_file_avail_update,
mmap_forward: snd_pcm_file_mmap_forward,
mmap_commit: snd_pcm_file_mmap_commit,
};
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int fd, const char *fmt, snd_pcm_t *slave, int close_slave)

View file

@ -449,7 +449,9 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
return 0;
}
static snd_pcm_sframes_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
snd_pcm_uframes_t size)
{
if (!(pcm->info & SND_PCM_INFO_MMAP) &&
pcm->stream == SND_PCM_STREAM_PLAYBACK)
@ -526,7 +528,7 @@ snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
readi: snd_pcm_hw_readi,
readn: snd_pcm_hw_readn,
avail_update: snd_pcm_hw_avail_update,
mmap_forward: snd_pcm_hw_mmap_forward,
mmap_commit: snd_pcm_hw_mmap_commit,
};
static int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode)

View file

@ -114,7 +114,7 @@ typedef struct {
snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
snd_pcm_sframes_t (*mmap_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t size);
snd_pcm_sframes_t (*mmap_commit)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
} snd_pcm_fast_ops_t;
struct _snd_pcm {
@ -209,9 +209,11 @@ void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
typedef snd_pcm_uframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
@ -279,6 +281,26 @@ static inline snd_pcm_sframes_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
return pcm->buffer_size - avail;
}
static inline const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
{
if (pcm->stopped_areas &&
snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING)
return pcm->stopped_areas;
return pcm->running_areas;
}
static inline snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
{
assert(pcm);
return *pcm->appl_ptr % pcm->buffer_size;
}
static inline snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
{
assert(pcm);
return *pcm->hw_ptr % pcm->buffer_size;
}
#define snd_pcm_mmap_playback_delay snd_pcm_mmap_playback_hw_avail
#define snd_pcm_mmap_capture_delay snd_pcm_mmap_capture_avail

View file

@ -385,11 +385,13 @@ static snd_pcm_sframes_t snd_pcm_meter_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
return err;
}
static snd_pcm_sframes_t snd_pcm_meter_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_meter_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
{
snd_pcm_meter_t *meter = pcm->private_data;
snd_pcm_uframes_t old_rptr = *pcm->appl_ptr;
snd_pcm_sframes_t result = snd_pcm_mmap_forward(meter->slave, size);
snd_pcm_sframes_t result = snd_pcm_mmap_commit(meter->slave, offset, size);
if (result <= 0)
return result;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
@ -594,7 +596,7 @@ snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
readi: snd_pcm_mmap_readi,
readn: snd_pcm_mmap_readn,
avail_update: snd_pcm_meter_avail_update,
mmap_forward: snd_pcm_meter_mmap_forward,
mmap_commit: snd_pcm_meter_mmap_commit,
};
int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequency,

View file

@ -44,36 +44,6 @@ size_t page_align(size_t size)
return size;
}
snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_uframes_t cont;
snd_pcm_uframes_t avail = snd_pcm_mmap_playback_avail(pcm);
if (avail < frames)
frames = avail;
cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
if (cont < frames)
frames = cont;
return frames;
}
snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_uframes_t cont;
snd_pcm_uframes_t avail = snd_pcm_mmap_capture_avail(pcm);
if (avail < frames)
frames = avail;
cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
if (cont < frames)
frames = cont;
return frames;
}
snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
{
assert(pcm);
return *pcm->hw_ptr % pcm->buffer_size;
}
void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_sframes_t appl_ptr = *pcm->appl_ptr;
@ -115,28 +85,18 @@ static snd_pcm_uframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
{
const snd_pcm_channel_area_t *pcm_areas;
snd_pcm_uframes_t pcm_offset;
snd_pcm_uframes_t xfer = size;
assert(snd_pcm_mmap_playback_avail(pcm) >= size);
pcm_areas = snd_pcm_mmap_areas(pcm);
pcm_offset = snd_pcm_mmap_offset(pcm);
while (size > 0) {
const snd_pcm_channel_area_t *pcm_areas;
snd_pcm_uframes_t pcm_offset;
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t cont = pcm->buffer_size - pcm_offset;
int err;
if (frames > cont)
frames = cont;
snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
snd_pcm_areas_copy(pcm_areas, pcm_offset,
areas, offset,
pcm->channels,
frames, pcm->format);
err = snd_pcm_mmap_forward(pcm, frames);
assert(err == (snd_pcm_sframes_t)frames);
if (frames == cont)
pcm_offset = 0;
else
pcm_offset += frames;
snd_pcm_mmap_commit(pcm, pcm_offset, frames);
offset += frames;
size -= frames;
}
@ -148,28 +108,18 @@ static snd_pcm_uframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
{
const snd_pcm_channel_area_t *pcm_areas;
snd_pcm_uframes_t pcm_offset;
snd_pcm_uframes_t xfer = size;
assert(snd_pcm_mmap_capture_avail(pcm) >= size);
pcm_areas = snd_pcm_mmap_areas(pcm);
pcm_offset = snd_pcm_mmap_offset(pcm);
while (size > 0) {
const snd_pcm_channel_area_t *pcm_areas;
snd_pcm_uframes_t pcm_offset;
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t cont = pcm->buffer_size - pcm_offset;
int err;
if (frames > cont)
frames = cont;
snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
snd_pcm_areas_copy(areas, offset,
pcm_areas, pcm_offset,
pcm->channels,
frames, pcm->format);
err = snd_pcm_mmap_forward(pcm, frames);
assert(err == (snd_pcm_sframes_t)frames);
if (frames == cont)
pcm_offset = 0;
else
pcm_offset += frames;
snd_pcm_mmap_commit(pcm, pcm_offset, frames);
offset += frames;
size -= frames;
}

View file

@ -30,6 +30,7 @@ typedef struct {
snd_pcm_t *pcm;
unsigned int channels_count;
int close_slave;
int linked;
} snd_pcm_multi_slave_t;
typedef struct {
@ -50,14 +51,12 @@ static int snd_pcm_multi_close(snd_pcm_t *pcm)
unsigned int i;
int ret = 0;
for (i = 0; i < multi->slaves_count; ++i) {
int err;
snd_pcm_multi_slave_t *slave = &multi->slaves[i];
if (slave->close_slave)
err = snd_pcm_close(slave->pcm);
else
err = snd_pcm_unlink(slave->pcm);
if (err < 0)
ret = err;
if (slave->close_slave) {
int err = snd_pcm_close(slave->pcm);
if (err < 0)
ret = err;
}
}
free(multi->slaves);
free(multi->channels);
@ -249,7 +248,7 @@ static int snd_pcm_multi_hw_params_slave(snd_pcm_t *pcm,
{
snd_pcm_multi_t *multi = pcm->private_data;
snd_pcm_t *slave = multi->slaves[slave_idx].pcm;
int err = snd_pcm_hw_refine(slave, sparams);
int err = snd_pcm_hw_params(slave, sparams);
if (err < 0)
return err;
err = snd_pcm_areas_silence(slave->running_areas, 0, slave->channels, slave->buffer_size, slave->format);
@ -266,20 +265,25 @@ static int snd_pcm_multi_hw_params_slave(snd_pcm_t *pcm,
static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_multi_t *multi = pcm->private_data;
unsigned int k;
unsigned int i;
snd_pcm_hw_params_t sparams[multi->slaves_count];
int err;
for (k = 0; k < multi->slaves_count; ++k) {
err = snd_pcm_multi_hw_refine_sprepare(pcm, k, &sparams[k]);
for (i = 0; i < multi->slaves_count; ++i) {
err = snd_pcm_multi_hw_refine_sprepare(pcm, i, &sparams[i]);
assert(err >= 0);
err = snd_pcm_multi_hw_refine_schange(pcm, k, params, &sparams[k]);
err = snd_pcm_multi_hw_refine_schange(pcm, i, params, &sparams[i]);
assert(err >= 0);
err = snd_pcm_multi_hw_params_slave(pcm, k, &sparams[k]);
err = snd_pcm_multi_hw_params_slave(pcm, i, &sparams[i]);
if (err < 0) {
snd_pcm_multi_hw_refine_cchange(pcm, k, params, &sparams[k]);
snd_pcm_multi_hw_refine_cchange(pcm, i, params, &sparams[i]);
return err;
}
}
multi->slaves[0].linked = 0;
for (i = 1; i < multi->slaves_count; ++i) {
err = snd_pcm_link(multi->slaves[0].pcm, multi->slaves[i].pcm);
multi->slaves[i].linked = (err >= 0);
}
return 0;
}
@ -293,6 +297,11 @@ static int snd_pcm_multi_hw_free(snd_pcm_t *pcm)
int e = snd_pcm_hw_free(slave);
if (e < 0)
err = e;
if (!multi->slaves[i].linked)
continue;
e = snd_pcm_unlink(slave);
if (e < 0)
err = e;
}
return err;
}
@ -335,44 +344,107 @@ static int snd_pcm_multi_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
static snd_pcm_sframes_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
snd_pcm_t *slave = multi->slaves[0].pcm;
return snd_pcm_avail_update(slave);
snd_pcm_sframes_t ret = LONG_MAX;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_sframes_t avail;
avail = snd_pcm_avail_update(multi->slaves[i].pcm);
if (avail < 0)
return avail;
if (ret > avail)
ret = avail;
}
return ret;
}
static int snd_pcm_multi_prepare(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
return snd_pcm_prepare(multi->slaves[0].pcm);
int err = 0;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (multi->slaves[i].linked)
continue;
err = snd_pcm_prepare(multi->slaves[i].pcm);
if (err < 0)
return err;
}
return err;
}
static int snd_pcm_multi_reset(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
return snd_pcm_reset(multi->slaves[0].pcm);
int err = 0;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (multi->slaves[i].linked)
continue;
err = snd_pcm_reset(multi->slaves[i].pcm);
if (err < 0)
return err;
}
return err;
}
static int snd_pcm_multi_start(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
return snd_pcm_start(multi->slaves[0].pcm);
int err = 0;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (multi->slaves[i].linked)
continue;
err = snd_pcm_start(multi->slaves[i].pcm);
if (err < 0)
return err;
}
return err;
}
static int snd_pcm_multi_drop(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
return snd_pcm_drop(multi->slaves[0].pcm);
int err = 0;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (multi->slaves[i].linked)
continue;
err = snd_pcm_drop(multi->slaves[i].pcm);
if (err < 0)
return err;
}
return err;
}
static int snd_pcm_multi_drain(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
return snd_pcm_drain(multi->slaves[0].pcm);
int err = 0;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (multi->slaves[i].linked)
continue;
err = snd_pcm_drain(multi->slaves[i].pcm);
if (err < 0)
return err;
}
return err;
}
static int snd_pcm_multi_pause(snd_pcm_t *pcm, int enable)
{
snd_pcm_multi_t *multi = pcm->private_data;
return snd_pcm_pause(multi->slaves[0].pcm, enable);
int err = 0;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (multi->slaves[i].linked)
continue;
err = snd_pcm_pause(multi->slaves[i].pcm, enable);
if (err < 0)
return err;
}
return err;
}
static int snd_pcm_multi_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
@ -408,19 +480,21 @@ static snd_pcm_sframes_t snd_pcm_multi_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
snd_pcm_t *slave_i = multi->slaves[i].pcm;
snd_pcm_uframes_t f = pos[i] - frames;
if (f > 0)
snd_pcm_mmap_forward(slave_i, f);
snd_pcm_mmap_commit(slave_i, snd_pcm_mmap_offset(slave_i), f);
}
return frames;
}
static snd_pcm_sframes_t snd_pcm_multi_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_multi_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
{
snd_pcm_multi_t *multi = pcm->private_data;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_t *slave = multi->slaves[i].pcm;
snd_pcm_sframes_t frames = snd_pcm_mmap_forward(slave, size);
snd_pcm_sframes_t frames = snd_pcm_mmap_commit(slave, offset, size);
if (frames < 0)
return frames;
if (i == 0) {
@ -497,7 +571,7 @@ snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
readn: snd_pcm_mmap_readn,
rewind: snd_pcm_multi_rewind,
avail_update: snd_pcm_multi_avail_update,
mmap_forward: snd_pcm_multi_mmap_forward,
mmap_commit: snd_pcm_multi_mmap_commit,
};
int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
@ -534,8 +608,6 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
slave->pcm = slaves_pcm[i];
slave->channels_count = schannels_count[i];
slave->close_slave = close_slaves;
if (i != 0)
snd_pcm_link(slaves_pcm[i-1], slaves_pcm[i]);
}
for (i = 0; i < channels_count; ++i) {
snd_pcm_multi_channel_t *bind = &multi->channels[i];

View file

@ -219,7 +219,9 @@ static snd_pcm_sframes_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUT
return snd_pcm_null_fwd(pcm, size);
}
static snd_pcm_sframes_t snd_pcm_null_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_null_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
snd_pcm_uframes_t size)
{
return snd_pcm_null_fwd(pcm, size);
}
@ -316,7 +318,7 @@ snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
readi: snd_pcm_null_readi,
readn: snd_pcm_null_readn,
avail_update: snd_pcm_null_avail_update,
mmap_forward: snd_pcm_null_mmap_forward,
mmap_commit: snd_pcm_null_mmap_commit,
};
int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)

View file

@ -198,29 +198,22 @@ static snd_pcm_uframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
{
snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_t *slave = plugin->slave;
const snd_pcm_channel_area_t *slave_areas;
snd_pcm_uframes_t slave_offset;
snd_pcm_uframes_t xfer = size;
slave_areas = snd_pcm_mmap_areas(slave);
slave_offset = snd_pcm_mmap_offset(slave);
while (size > 0) {
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
snd_pcm_uframes_t slave_frames = slave_cont;
const snd_pcm_channel_area_t *slave_areas;
snd_pcm_uframes_t slave_offset, slave_frames;
snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
frames = plugin->write(pcm, areas, offset, frames,
slave_areas, slave_offset, &slave_frames);
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_hw_forward(pcm, frames);
snd_pcm_mmap_forward(slave, slave_frames);
snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
snd_atomic_write_end(&plugin->watom);
offset += frames;
size -= frames;
if (slave_frames == slave_cont)
slave_offset = 0;
else
slave_offset += slave_frames;
}
return xfer;
}
@ -232,29 +225,22 @@ static snd_pcm_uframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
{
snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_t *slave = plugin->slave;
const snd_pcm_channel_area_t *slave_areas;
snd_pcm_uframes_t slave_offset;
snd_pcm_uframes_t xfer = size;
slave_areas = snd_pcm_mmap_areas(slave);
slave_offset = snd_pcm_mmap_offset(slave);
while (size > 0) {
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
snd_pcm_uframes_t slave_frames = slave_cont;
const snd_pcm_channel_area_t *slave_areas;
snd_pcm_uframes_t slave_offset, slave_frames;
snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
frames = plugin->read(pcm, areas, offset, frames,
slave_areas, slave_offset, &slave_frames);
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_hw_forward(pcm, frames);
snd_pcm_mmap_forward(slave, slave_frames);
snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
snd_atomic_write_end(&plugin->watom);
offset += frames;
size -= frames;
if (slave_frames == slave_cont)
slave_offset = 0;
else
slave_offset += slave_frames;
}
return xfer;
}
@ -292,13 +278,15 @@ snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_ufra
snd_pcm_plugin_read_areas);
}
snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
snd_pcm_uframes_t size)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_t *slave = plugin->slave;
const snd_pcm_channel_area_t *areas, *slave_areas;
snd_pcm_uframes_t xfer, offset;
snd_pcm_uframes_t slave_offset, slave_size;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t xfer, hw_offset;
snd_pcm_uframes_t slave_size;
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
snd_atomic_write_begin(&plugin->watom);
snd_pcm_mmap_appl_forward(pcm, size);
@ -309,36 +297,29 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
if (slave_size <= 0)
return slave_size;
areas = snd_pcm_mmap_areas(pcm);
offset = snd_pcm_mmap_hw_offset(pcm);
slave_areas = snd_pcm_mmap_areas(slave);
slave_offset = snd_pcm_mmap_offset(slave);
hw_offset = snd_pcm_mmap_hw_offset(pcm);
xfer = 0;
while (size && slave_size) {
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t cont = pcm->buffer_size - offset;
snd_pcm_uframes_t slave_frames = slave_size;
snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset;
const snd_pcm_channel_area_t *slave_areas;
snd_pcm_uframes_t slave_offset, slave_frames;
snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
if (frames > cont)
frames = cont;
if (slave_frames > slave_cont)
slave_frames = slave_cont;
frames = plugin->write(pcm, areas, offset, frames,
frames = plugin->write(pcm, areas, hw_offset, frames,
slave_areas, slave_offset, &slave_frames);
snd_atomic_write_begin(&plugin->watom);
snd_pcm_mmap_appl_forward(pcm, frames);
snd_pcm_mmap_hw_forward(pcm, frames);
snd_pcm_mmap_forward(slave, slave_frames);
snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
snd_atomic_write_end(&plugin->watom);
xfer += frames;
if (frames == cont)
offset = 0;
hw_offset = 0;
else
offset += frames;
hw_offset += frames;
size -= frames;
if (slave_frames == slave_cont)
slave_offset = 0;
else
slave_offset += slave_frames;
slave_size -= slave_frames;
}
return xfer;
@ -348,9 +329,8 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_t *slave = plugin->slave;
const snd_pcm_channel_area_t *areas, *slave_areas;
snd_pcm_uframes_t xfer, offset, size;
snd_pcm_uframes_t slave_offset;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t xfer, hw_offset, size;
snd_pcm_sframes_t slave_size;
slave_size = snd_pcm_avail_update(slave);
if (slave_size <= 0)
@ -364,34 +344,27 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
xfer = snd_pcm_mmap_capture_avail(pcm);
size = pcm->buffer_size - xfer;
areas = snd_pcm_mmap_areas(pcm);
offset = snd_pcm_mmap_hw_offset(pcm);
slave_areas = snd_pcm_mmap_areas(slave);
slave_offset = snd_pcm_mmap_offset(slave);
hw_offset = snd_pcm_mmap_hw_offset(pcm);
while (size && slave_size) {
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t cont = pcm->buffer_size - offset;
snd_pcm_uframes_t slave_frames = slave_size;
snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset;
const snd_pcm_channel_area_t *slave_areas;
snd_pcm_uframes_t slave_offset, slave_frames;
snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
if (frames > cont)
frames = cont;
if (slave_frames > slave_cont)
slave_frames = slave_cont;
frames = plugin->read(pcm, areas, offset, frames,
frames = plugin->read(pcm, areas, hw_offset, frames,
slave_areas, slave_offset, &slave_frames);
snd_atomic_write_begin(&plugin->watom);
snd_pcm_mmap_hw_forward(pcm, frames);
snd_pcm_mmap_forward(slave, slave_frames);
snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
snd_atomic_write_end(&plugin->watom);
xfer += frames;
if (frames == cont)
offset = 0;
hw_offset = 0;
else
offset += frames;
hw_offset += frames;
size -= frames;
if (slave_frames == slave_cont)
slave_offset = 0;
else
slave_offset += slave_frames;
slave_size -= slave_frames;
}
return xfer;
@ -474,6 +447,6 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
readi: snd_pcm_plugin_readi,
readn: snd_pcm_plugin_readn,
avail_update: snd_pcm_plugin_avail_update,
mmap_forward: snd_pcm_plugin_mmap_forward,
mmap_commit: snd_pcm_plugin_mmap_commit,
};

View file

@ -65,7 +65,7 @@ snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_
snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
int snd_pcm_plugin_mmap_status(snd_pcm_t *pcm);
int snd_pcm_plugin_mmap_control(snd_pcm_t *pcm);

View file

@ -118,7 +118,7 @@ static snd_pcm_uframes_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
}
/* Warning: take the mutex before to call this */
/* Return number of frames to mmap_forward the slave */
/* Return number of frames to mmap_commit the slave */
static snd_pcm_uframes_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
{
struct list_head *i;
@ -223,7 +223,7 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
frames = -safety_missing;
missing = 1;
}
err = snd_pcm_mmap_forward(spcm, frames);
err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
assert(err == frames);
slave_avail -= frames;
} else {
@ -756,22 +756,25 @@ static snd_pcm_sframes_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
}
/* Call it with mutex held */
static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t _snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
snd_pcm_uframes_t size)
{
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_t *spcm = slave->pcm;
snd_pcm_sframes_t ret = 0;
snd_pcm_sframes_t frames;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
share->state == SND_PCM_STATE_RUNNING) {
frames = *slave->pcm->appl_ptr - share->appl_ptr;
frames = *spcm->appl_ptr - share->appl_ptr;
if (frames > (snd_pcm_sframes_t)pcm->buffer_size)
frames -= pcm->boundary;
else if (frames < -(snd_pcm_sframes_t)pcm->buffer_size)
frames += pcm->boundary;
if (frames > 0) {
/* Latecomer PCM */
ret = snd_pcm_rewind(slave->pcm, frames);
ret = snd_pcm_rewind(spcm, frames);
if (ret < 0)
return ret;
}
@ -781,7 +784,7 @@ static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_ufr
frames = _snd_pcm_share_slave_forward(slave);
if (frames > 0) {
snd_pcm_sframes_t err;
err = snd_pcm_mmap_forward(slave->pcm, frames);
err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
assert(err == frames);
}
_snd_pcm_share_update(pcm);
@ -789,13 +792,15 @@ static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_ufr
return size;
}
static snd_pcm_sframes_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
{
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_sframes_t ret;
Pthread_mutex_lock(&slave->mutex);
ret = _snd_pcm_share_mmap_forward(pcm, size);
ret = _snd_pcm_share_mmap_commit(pcm, offset, size);
Pthread_mutex_unlock(&slave->mutex);
return ret;
}
@ -838,6 +843,7 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
{
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_t *spcm = slave->pcm;
int err = 0;
if (share->state != SND_PCM_STATE_PREPARED)
return -EBADFD;
@ -852,16 +858,16 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
}
if (slave->running_count) {
snd_pcm_sframes_t sd;
err = snd_pcm_delay(slave->pcm, &sd);
err = snd_pcm_delay(spcm, &sd);
if (err < 0)
goto _end;
err = snd_pcm_rewind(slave->pcm, sd);
err = snd_pcm_rewind(spcm, sd);
if (err < 0)
goto _end;
}
assert(share->hw_ptr == 0);
share->hw_ptr = *slave->pcm->hw_ptr;
share->appl_ptr = *slave->pcm->appl_ptr;
share->hw_ptr = *spcm->hw_ptr;
share->appl_ptr = *spcm->appl_ptr;
while (xfer < hw_avail) {
snd_pcm_uframes_t frames = hw_avail - xfer;
snd_pcm_uframes_t offset = snd_pcm_mmap_offset(pcm);
@ -877,10 +883,10 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
}
snd_pcm_mmap_appl_forward(pcm, hw_avail);
if (slave->running_count == 0)
snd_pcm_mmap_forward(slave->pcm, hw_avail);
snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), hw_avail);
}
if (slave->running_count == 0) {
err = snd_pcm_start(slave->pcm);
err = snd_pcm_start(spcm);
if (err < 0)
goto _end;
}
@ -1181,7 +1187,7 @@ snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
readn: snd_pcm_mmap_readn,
rewind: snd_pcm_share_rewind,
avail_update: snd_pcm_share_avail_update,
mmap_forward: snd_pcm_share_mmap_forward,
mmap_commit: snd_pcm_share_mmap_commit,
};
int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,

View file

@ -435,12 +435,15 @@ static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fr
return snd_pcm_shm_action(pcm);
}
static snd_pcm_sframes_t snd_pcm_shm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_shm_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
snd_pcm_uframes_t size)
{
snd_pcm_shm_t *shm = pcm->private_data;
volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
ctrl->cmd = SND_PCM_IOCTL_MMAP_FORWARD;
ctrl->u.mmap_forward.frames = size;
ctrl->cmd = SND_PCM_IOCTL_MMAP_COMMIT;
ctrl->u.mmap_commit.offset = offset;
ctrl->u.mmap_commit.frames = size;
return snd_pcm_shm_action(pcm);
}
@ -510,7 +513,7 @@ snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
readi: snd_pcm_mmap_readi,
readn: snd_pcm_mmap_readn,
avail_update: snd_pcm_shm_avail_update,
mmap_forward: snd_pcm_shm_mmap_forward,
mmap_commit: snd_pcm_shm_mmap_commit,
};
static int make_local_socket(const char *filename)

View file

@ -207,13 +207,13 @@ static snd_pcm_sframes_t snd_pcm_surround_readn(snd_pcm_t *pcm, void **bufs, snd
return res;
}
static snd_pcm_sframes_t snd_pcm_surround_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
static snd_pcm_sframes_t snd_pcm_surround_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size)
{
int i;
snd_pcm_sframes_t res = -1, res1;
snd_pcm_surround_t *surr = pcm->private_data;
for (i = 0; i < surr->pcms; i++) {
res1 = snd_pcm_mmap_forward(surr->pcm[i], size);
res1 = snd_pcm_mmap_commit(surr->pcm[i], offset, size);
if (res1 < 0)
return res1;
if (res < 0) {
@ -367,7 +367,7 @@ snd_pcm_fast_ops_t snd_pcm_surround_fast_ops = {
readi: snd_pcm_surround_readi,
readn: snd_pcm_surround_readn,
avail_update: snd_pcm_surround_avail_update,
mmap_forward: snd_pcm_surround_mmap_forward,
mmap_commit: snd_pcm_surround_mmap_commit,
};
int snd_pcm_surround_open(snd_pcm_t **pcmp, const char *name, int card, int dev,