mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Synchronized snd_pcm_write_areas and snd_pcm_read_areas with the kernel
write/read functions. Changed snd_pcm_xfer_areas_func_t to return snd_pcm_sframes_t (pass errors).
This commit is contained in:
parent
9d34cf954a
commit
b63e44aab0
5 changed files with 56 additions and 29 deletions
|
|
@ -4945,7 +4945,7 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
|
||||||
snd_pcm_xfer_areas_func_t func)
|
snd_pcm_xfer_areas_func_t func)
|
||||||
{
|
{
|
||||||
snd_pcm_uframes_t xfer = 0;
|
snd_pcm_uframes_t xfer = 0;
|
||||||
int err = 0;
|
snd_pcm_sframes_t err = 0;
|
||||||
snd_pcm_state_t state = snd_pcm_state(pcm);
|
snd_pcm_state_t state = snd_pcm_state(pcm);
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
@ -4976,17 +4976,17 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
|
||||||
_again:
|
_again:
|
||||||
avail = snd_pcm_avail_update(pcm);
|
avail = snd_pcm_avail_update(pcm);
|
||||||
if (avail < 0) {
|
if (avail < 0) {
|
||||||
err = -EPIPE;
|
err = avail;
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
if (state == SND_PCM_STATE_DRAINING) {
|
if ((state == SND_PCM_STATE_PAUSED) ||
|
||||||
if (avail == 0) {
|
(state == SND_PCM_STATE_DRAINING)) {
|
||||||
|
if ((snd_pcm_uframes_t)avail < pcm->xfer_align) {
|
||||||
err = -EPIPE;
|
err = -EPIPE;
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
} else if (avail == 0 ||
|
} else if (((snd_pcm_uframes_t)avail < pcm->avail_min && size > (snd_pcm_uframes_t)avail) ||
|
||||||
(size >= pcm->xfer_align &&
|
(size >= pcm->xfer_align && (snd_pcm_uframes_t)avail < pcm->xfer_align)) {
|
||||||
(snd_pcm_uframes_t) avail < pcm->xfer_align)) {
|
|
||||||
if (pcm->mode & SND_PCM_NONBLOCK) {
|
if (pcm->mode & SND_PCM_NONBLOCK) {
|
||||||
err = -EAGAIN;
|
err = -EAGAIN;
|
||||||
goto _end;
|
goto _end;
|
||||||
|
|
@ -5029,7 +5029,7 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
|
||||||
snd_pcm_xfer_areas_func_t func)
|
snd_pcm_xfer_areas_func_t func)
|
||||||
{
|
{
|
||||||
snd_pcm_uframes_t xfer = 0;
|
snd_pcm_uframes_t xfer = 0;
|
||||||
int err = 0;
|
snd_pcm_sframes_t err = 0;
|
||||||
snd_pcm_state_t state = snd_pcm_state(pcm);
|
snd_pcm_state_t state = snd_pcm_state(pcm);
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
@ -5051,19 +5051,26 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
|
||||||
snd_pcm_uframes_t frames;
|
snd_pcm_uframes_t frames;
|
||||||
snd_pcm_sframes_t avail;
|
snd_pcm_sframes_t avail;
|
||||||
_again:
|
_again:
|
||||||
|
if (pcm->sleep_min == 0 && state == SND_PCM_STATE_RUNNING) {
|
||||||
|
snd_pcm_sframes_t delay;
|
||||||
|
/* update hw_ptr */
|
||||||
|
err = snd_pcm_delay(pcm, &delay);
|
||||||
|
if (err < 0)
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
avail = snd_pcm_avail_update(pcm);
|
avail = snd_pcm_avail_update(pcm);
|
||||||
if (avail < 0) {
|
if (avail < 0) {
|
||||||
err = -EPIPE;
|
err = avail;
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
if (state == SND_PCM_STATE_PREPARED) {
|
if (state == SND_PCM_STATE_PAUSED ||
|
||||||
if (avail == 0) {
|
state == SND_PCM_STATE_PREPARED) {
|
||||||
|
if ((snd_pcm_uframes_t)avail < pcm->xfer_align) {
|
||||||
err = -EPIPE;
|
err = -EPIPE;
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
} else if (avail == 0 ||
|
} else if (((snd_pcm_uframes_t)avail < pcm->avail_min && size > (snd_pcm_uframes_t)avail) ||
|
||||||
(size >= pcm->xfer_align &&
|
(size >= pcm->xfer_align && (snd_pcm_uframes_t)avail < pcm->xfer_align)) {
|
||||||
(snd_pcm_uframes_t) avail < pcm->xfer_align)) {
|
|
||||||
if (pcm->mode & SND_PCM_NONBLOCK) {
|
if (pcm->mode & SND_PCM_NONBLOCK) {
|
||||||
err = -EAGAIN;
|
err = -EAGAIN;
|
||||||
goto _end;
|
goto _end;
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_ufram
|
||||||
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_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);
|
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,
|
typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas,
|
const snd_pcm_channel_area_t *areas,
|
||||||
snd_pcm_uframes_t offset,
|
snd_pcm_uframes_t offset,
|
||||||
snd_pcm_uframes_t size);
|
snd_pcm_uframes_t size);
|
||||||
|
|
|
||||||
|
|
@ -80,12 +80,14 @@ void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
|
||||||
*pcm->hw_ptr = hw_ptr;
|
*pcm->hw_ptr = hw_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_uframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
|
static snd_pcm_sframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas,
|
const snd_pcm_channel_area_t *areas,
|
||||||
snd_pcm_uframes_t offset,
|
snd_pcm_uframes_t offset,
|
||||||
snd_pcm_uframes_t size)
|
snd_pcm_uframes_t size)
|
||||||
{
|
{
|
||||||
snd_pcm_uframes_t xfer = size;
|
snd_pcm_uframes_t xfer = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
assert(snd_pcm_mmap_playback_avail(pcm) >= size);
|
assert(snd_pcm_mmap_playback_avail(pcm) >= size);
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
const snd_pcm_channel_area_t *pcm_areas;
|
const snd_pcm_channel_area_t *pcm_areas;
|
||||||
|
|
@ -96,31 +98,39 @@ static snd_pcm_uframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
|
||||||
areas, offset,
|
areas, offset,
|
||||||
pcm->channels,
|
pcm->channels,
|
||||||
frames, pcm->format);
|
frames, pcm->format);
|
||||||
snd_pcm_mmap_commit(pcm, pcm_offset, frames);
|
err = snd_pcm_mmap_commit(pcm, pcm_offset, frames);
|
||||||
|
if (err < 0)
|
||||||
|
return xfer > 0 ? xfer : err;
|
||||||
offset += frames;
|
offset += frames;
|
||||||
|
xfer += frames;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
}
|
}
|
||||||
return xfer;
|
return xfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_uframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
|
static snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas,
|
const snd_pcm_channel_area_t *areas,
|
||||||
snd_pcm_uframes_t offset,
|
snd_pcm_uframes_t offset,
|
||||||
snd_pcm_uframes_t size)
|
snd_pcm_uframes_t size)
|
||||||
{
|
{
|
||||||
snd_pcm_uframes_t xfer = size;
|
snd_pcm_uframes_t xfer = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
assert(snd_pcm_mmap_capture_avail(pcm) >= size);
|
assert(snd_pcm_mmap_capture_avail(pcm) >= size);
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
const snd_pcm_channel_area_t *pcm_areas;
|
const snd_pcm_channel_area_t *pcm_areas;
|
||||||
snd_pcm_uframes_t pcm_offset;
|
snd_pcm_uframes_t pcm_offset;
|
||||||
snd_pcm_uframes_t frames = size;
|
snd_pcm_uframes_t frames = size;
|
||||||
snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
|
snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
|
||||||
snd_pcm_areas_copy(areas, offset,
|
snd_pcm_areas_copy(areas, offset,
|
||||||
pcm_areas, pcm_offset,
|
pcm_areas, pcm_offset,
|
||||||
pcm->channels,
|
pcm->channels,
|
||||||
frames, pcm->format);
|
frames, pcm->format);
|
||||||
snd_pcm_mmap_commit(pcm, pcm_offset, frames);
|
err = snd_pcm_mmap_commit(pcm, pcm_offset, frames);
|
||||||
|
if (err < 0)
|
||||||
|
return xfer > 0 ? xfer : err;
|
||||||
offset += frames;
|
offset += frames;
|
||||||
|
xfer += frames;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
}
|
}
|
||||||
return xfer;
|
return xfer;
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ static snd_pcm_sframes_t snd_pcm_null_fwd(snd_pcm_t *pcm, snd_pcm_uframes_t size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_uframes_t snd_pcm_null_xfer_areas(snd_pcm_t *pcm,
|
static snd_pcm_sframes_t snd_pcm_null_xfer_areas(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas ATTRIBUTE_UNUSED,
|
const snd_pcm_channel_area_t *areas ATTRIBUTE_UNUSED,
|
||||||
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
|
snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
|
||||||
snd_pcm_uframes_t size)
|
snd_pcm_uframes_t size)
|
||||||
|
|
|
||||||
|
|
@ -197,14 +197,16 @@ int snd_pcm_plugin_resume(snd_pcm_t *pcm)
|
||||||
return snd_pcm_resume(plugin->slave);
|
return snd_pcm_resume(plugin->slave);
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_uframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas,
|
const snd_pcm_channel_area_t *areas,
|
||||||
snd_pcm_uframes_t offset,
|
snd_pcm_uframes_t offset,
|
||||||
snd_pcm_uframes_t size)
|
snd_pcm_uframes_t size)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
snd_pcm_t *slave = plugin->slave;
|
snd_pcm_t *slave = plugin->slave;
|
||||||
snd_pcm_uframes_t xfer = size;
|
snd_pcm_uframes_t xfer = 0;
|
||||||
|
snd_pcm_sframes_t err;
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
snd_pcm_uframes_t frames = size;
|
snd_pcm_uframes_t frames = size;
|
||||||
const snd_pcm_channel_area_t *slave_areas;
|
const snd_pcm_channel_area_t *slave_areas;
|
||||||
|
|
@ -217,22 +219,27 @@ static snd_pcm_uframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||||
snd_atomic_write_begin(&plugin->watom);
|
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_commit(slave, slave_offset, slave_frames);
|
err = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||||
snd_atomic_write_end(&plugin->watom);
|
snd_atomic_write_end(&plugin->watom);
|
||||||
|
if (err < 0)
|
||||||
|
return xfer > 0 ? xfer : err;
|
||||||
offset += frames;
|
offset += frames;
|
||||||
|
xfer += frames;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
}
|
}
|
||||||
return xfer;
|
return xfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_uframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||||
const snd_pcm_channel_area_t *areas,
|
const snd_pcm_channel_area_t *areas,
|
||||||
snd_pcm_uframes_t offset,
|
snd_pcm_uframes_t offset,
|
||||||
snd_pcm_uframes_t size)
|
snd_pcm_uframes_t size)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||||
snd_pcm_t *slave = plugin->slave;
|
snd_pcm_t *slave = plugin->slave;
|
||||||
snd_pcm_uframes_t xfer = size;
|
snd_pcm_uframes_t xfer = 0;
|
||||||
|
snd_pcm_sframes_t err;
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
snd_pcm_uframes_t frames = size;
|
snd_pcm_uframes_t frames = size;
|
||||||
const snd_pcm_channel_area_t *slave_areas;
|
const snd_pcm_channel_area_t *slave_areas;
|
||||||
|
|
@ -245,9 +252,12 @@ static snd_pcm_uframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||||
snd_atomic_write_begin(&plugin->watom);
|
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_commit(slave, slave_offset, slave_frames);
|
err = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||||
snd_atomic_write_end(&plugin->watom);
|
snd_atomic_write_end(&plugin->watom);
|
||||||
|
if (err < 0)
|
||||||
|
return xfer > 0 ? xfer : err;
|
||||||
offset += frames;
|
offset += frames;
|
||||||
|
xfer += frames;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
}
|
}
|
||||||
return xfer;
|
return xfer;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue