ALSA: pcm: Simplify forward/rewind codes

Factor out the common codes in snd_pcm_*_forward() and *_rewind()
functions to simplify the codes.  No functional changes.

Reviewd-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2017-05-19 20:16:44 +02:00
parent f839cc1cbd
commit e0327a0f21
1 changed files with 50 additions and 68 deletions

View File

@ -2455,34 +2455,58 @@ static int do_pcm_hwsync(struct snd_pcm_substream *substream)
} }
} }
/* increase the appl_ptr; returns the processed frames */
static snd_pcm_sframes_t forward_appl_ptr(struct snd_pcm_substream *substream,
snd_pcm_uframes_t frames,
snd_pcm_sframes_t avail)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t appl_ptr;
if (avail <= 0)
return 0;
if (frames > (snd_pcm_uframes_t)avail)
frames = avail;
appl_ptr = runtime->control->appl_ptr + frames;
if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
appl_ptr -= runtime->boundary;
runtime->control->appl_ptr = appl_ptr;
return frames;
}
/* decrease the appl_ptr; returns the processed frames */
static snd_pcm_sframes_t rewind_appl_ptr(struct snd_pcm_substream *substream,
snd_pcm_uframes_t frames,
snd_pcm_sframes_t avail)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t appl_ptr;
if (avail <= 0)
return 0;
if (frames > (snd_pcm_uframes_t)avail)
frames = avail;
appl_ptr = runtime->control->appl_ptr - frames;
if (appl_ptr < 0)
appl_ptr += runtime->boundary;
runtime->control->appl_ptr = appl_ptr;
return frames;
}
static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream, static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
snd_pcm_uframes_t frames) snd_pcm_uframes_t frames)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t appl_ptr;
snd_pcm_sframes_t ret; snd_pcm_sframes_t ret;
snd_pcm_sframes_t hw_avail;
if (frames == 0) if (frames == 0)
return 0; return 0;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
ret = do_pcm_hwsync(substream); ret = do_pcm_hwsync(substream);
if (ret < 0) if (!ret)
goto __end; ret = rewind_appl_ptr(substream, frames,
hw_avail = snd_pcm_playback_hw_avail(runtime); snd_pcm_playback_hw_avail(runtime));
if (hw_avail <= 0) {
ret = 0;
goto __end;
}
if (frames > (snd_pcm_uframes_t)hw_avail)
frames = hw_avail;
appl_ptr = runtime->control->appl_ptr - frames;
if (appl_ptr < 0)
appl_ptr += runtime->boundary;
runtime->control->appl_ptr = appl_ptr;
ret = frames;
__end:
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return ret; return ret;
} }
@ -2491,30 +2515,16 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
snd_pcm_uframes_t frames) snd_pcm_uframes_t frames)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t appl_ptr;
snd_pcm_sframes_t ret; snd_pcm_sframes_t ret;
snd_pcm_sframes_t hw_avail;
if (frames == 0) if (frames == 0)
return 0; return 0;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
ret = do_pcm_hwsync(substream); ret = do_pcm_hwsync(substream);
if (ret < 0) if (!ret)
goto __end; ret = rewind_appl_ptr(substream, frames,
hw_avail = snd_pcm_capture_hw_avail(runtime); snd_pcm_capture_hw_avail(runtime));
if (hw_avail <= 0) {
ret = 0;
goto __end;
}
if (frames > (snd_pcm_uframes_t)hw_avail)
frames = hw_avail;
appl_ptr = runtime->control->appl_ptr - frames;
if (appl_ptr < 0)
appl_ptr += runtime->boundary;
runtime->control->appl_ptr = appl_ptr;
ret = frames;
__end:
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return ret; return ret;
} }
@ -2523,30 +2533,16 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
snd_pcm_uframes_t frames) snd_pcm_uframes_t frames)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t appl_ptr;
snd_pcm_sframes_t ret; snd_pcm_sframes_t ret;
snd_pcm_sframes_t avail;
if (frames == 0) if (frames == 0)
return 0; return 0;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
ret = do_pcm_hwsync(substream); ret = do_pcm_hwsync(substream);
if (ret < 0) if (!ret)
goto __end; ret = forward_appl_ptr(substream, frames,
avail = snd_pcm_playback_avail(runtime); snd_pcm_playback_avail(runtime));
if (avail <= 0) {
ret = 0;
goto __end;
}
if (frames > (snd_pcm_uframes_t)avail)
frames = avail;
appl_ptr = runtime->control->appl_ptr + frames;
if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
appl_ptr -= runtime->boundary;
runtime->control->appl_ptr = appl_ptr;
ret = frames;
__end:
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return ret; return ret;
} }
@ -2555,30 +2551,16 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
snd_pcm_uframes_t frames) snd_pcm_uframes_t frames)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t appl_ptr;
snd_pcm_sframes_t ret; snd_pcm_sframes_t ret;
snd_pcm_sframes_t avail;
if (frames == 0) if (frames == 0)
return 0; return 0;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
ret = do_pcm_hwsync(substream); ret = do_pcm_hwsync(substream);
if (ret < 0) if (!ret)
goto __end; ret = forward_appl_ptr(substream, frames,
avail = snd_pcm_capture_avail(runtime); snd_pcm_capture_avail(runtime));
if (avail <= 0) {
ret = 0;
goto __end;
}
if (frames > (snd_pcm_uframes_t)avail)
frames = avail;
appl_ptr = runtime->control->appl_ptr + frames;
if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
appl_ptr -= runtime->boundary;
runtime->control->appl_ptr = appl_ptr;
ret = frames;
__end:
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return ret; return ret;
} }