|
@@ -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,
|
|
|
snd_pcm_uframes_t frames)
|
|
|
{
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
- snd_pcm_sframes_t appl_ptr;
|
|
|
snd_pcm_sframes_t ret;
|
|
|
- snd_pcm_sframes_t hw_avail;
|
|
|
|
|
|
if (frames == 0)
|
|
|
return 0;
|
|
|
|
|
|
snd_pcm_stream_lock_irq(substream);
|
|
|
ret = do_pcm_hwsync(substream);
|
|
|
- if (ret < 0)
|
|
|
- goto __end;
|
|
|
- hw_avail = 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:
|
|
|
+ if (!ret)
|
|
|
+ ret = rewind_appl_ptr(substream, frames,
|
|
|
+ snd_pcm_playback_hw_avail(runtime));
|
|
|
snd_pcm_stream_unlock_irq(substream);
|
|
|
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)
|
|
|
{
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
- snd_pcm_sframes_t appl_ptr;
|
|
|
snd_pcm_sframes_t ret;
|
|
|
- snd_pcm_sframes_t hw_avail;
|
|
|
|
|
|
if (frames == 0)
|
|
|
return 0;
|
|
|
|
|
|
snd_pcm_stream_lock_irq(substream);
|
|
|
ret = do_pcm_hwsync(substream);
|
|
|
- if (ret < 0)
|
|
|
- goto __end;
|
|
|
- hw_avail = 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:
|
|
|
+ if (!ret)
|
|
|
+ ret = rewind_appl_ptr(substream, frames,
|
|
|
+ snd_pcm_capture_hw_avail(runtime));
|
|
|
snd_pcm_stream_unlock_irq(substream);
|
|
|
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)
|
|
|
{
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
- snd_pcm_sframes_t appl_ptr;
|
|
|
snd_pcm_sframes_t ret;
|
|
|
- snd_pcm_sframes_t avail;
|
|
|
|
|
|
if (frames == 0)
|
|
|
return 0;
|
|
|
|
|
|
snd_pcm_stream_lock_irq(substream);
|
|
|
ret = do_pcm_hwsync(substream);
|
|
|
- if (ret < 0)
|
|
|
- goto __end;
|
|
|
- avail = 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:
|
|
|
+ if (!ret)
|
|
|
+ ret = forward_appl_ptr(substream, frames,
|
|
|
+ snd_pcm_playback_avail(runtime));
|
|
|
snd_pcm_stream_unlock_irq(substream);
|
|
|
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)
|
|
|
{
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
- snd_pcm_sframes_t appl_ptr;
|
|
|
snd_pcm_sframes_t ret;
|
|
|
- snd_pcm_sframes_t avail;
|
|
|
|
|
|
if (frames == 0)
|
|
|
return 0;
|
|
|
|
|
|
snd_pcm_stream_lock_irq(substream);
|
|
|
ret = do_pcm_hwsync(substream);
|
|
|
- if (ret < 0)
|
|
|
- goto __end;
|
|
|
- avail = 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:
|
|
|
+ if (!ret)
|
|
|
+ ret = forward_appl_ptr(substream, frames,
|
|
|
+ snd_pcm_capture_avail(runtime));
|
|
|
snd_pcm_stream_unlock_irq(substream);
|
|
|
return ret;
|
|
|
}
|