mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-05 13:30:00 -05:00
pcm: fix read_areas and write_areas
The stream state was wrongly updated and handled. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
63acb87329
commit
2e48439ad9
1 changed files with 48 additions and 39 deletions
|
|
@ -6528,46 +6528,51 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
|
|||
{
|
||||
snd_pcm_uframes_t xfer = 0;
|
||||
snd_pcm_sframes_t err = 0;
|
||||
snd_pcm_state_t state = snd_pcm_state(pcm);
|
||||
snd_pcm_state_t state;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
while (size > 0) {
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_sframes_t avail;
|
||||
_again:
|
||||
state = snd_pcm_state(pcm);
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
err = snd_pcm_start(pcm);
|
||||
if (err < 0)
|
||||
goto _end;
|
||||
break;
|
||||
case SND_PCM_STATE_DRAINING:
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
break;
|
||||
case SND_PCM_STATE_XRUN:
|
||||
return -EPIPE;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
return -ESTRPIPE;
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
return -ENODEV;
|
||||
default:
|
||||
return -EBADFD;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_sframes_t avail;
|
||||
_again:
|
||||
if (state == SND_PCM_STATE_RUNNING) {
|
||||
err = snd_pcm_hwsync(pcm);
|
||||
if (err < 0)
|
||||
goto _end;
|
||||
break;
|
||||
case SND_PCM_STATE_DRAINING:
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
break;
|
||||
case SND_PCM_STATE_XRUN:
|
||||
err = -EPIPE;
|
||||
goto _end;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
err = -ESTRPIPE;
|
||||
goto _end;
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
err = -ENODEV;
|
||||
goto _end;
|
||||
default:
|
||||
err = -EBADFD;
|
||||
goto _end;
|
||||
}
|
||||
avail = snd_pcm_avail_update(pcm);
|
||||
if (avail < 0) {
|
||||
err = avail;
|
||||
goto _end;
|
||||
}
|
||||
if ((snd_pcm_uframes_t)avail < pcm->avail_min &&
|
||||
size > (snd_pcm_uframes_t)avail) {
|
||||
if (avail == 0) {
|
||||
if (state == SND_PCM_STATE_DRAINING)
|
||||
goto _end;
|
||||
if (pcm->mode & SND_PCM_NONBLOCK) {
|
||||
err = -EAGAIN;
|
||||
goto _end;
|
||||
|
|
@ -6602,33 +6607,37 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
|
|||
{
|
||||
snd_pcm_uframes_t xfer = 0;
|
||||
snd_pcm_sframes_t err = 0;
|
||||
snd_pcm_state_t state = snd_pcm_state(pcm);
|
||||
snd_pcm_state_t state;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
break;
|
||||
case SND_PCM_STATE_XRUN:
|
||||
return -EPIPE;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
return -ESTRPIPE;
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
return -ENODEV;
|
||||
default:
|
||||
return -EBADFD;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_sframes_t avail;
|
||||
_again:
|
||||
if (state == SND_PCM_STATE_RUNNING) {
|
||||
state = snd_pcm_state(pcm);
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
break;
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
err = snd_pcm_hwsync(pcm);
|
||||
if (err < 0)
|
||||
goto _end;
|
||||
break;
|
||||
case SND_PCM_STATE_XRUN:
|
||||
err = -EPIPE;
|
||||
goto _end;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
err = -ESTRPIPE;
|
||||
goto _end;
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
err = -ENODEV;
|
||||
goto _end;
|
||||
default:
|
||||
err = -EBADFD;
|
||||
goto _end;
|
||||
}
|
||||
avail = snd_pcm_avail_update(pcm);
|
||||
if (avail < 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue