aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h1
-rw-r--r--sound/core/oss/pcm_oss.c3
-rw-r--r--sound/core/pcm_lib.c7
-rw-r--r--sound/core/pcm_native.c2
4 files changed, 9 insertions, 4 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 3bc9bca..13bc83c 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -271,6 +271,7 @@ struct snd_pcm_runtime {
int overrange;
snd_pcm_uframes_t avail_max;
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
+ snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 255ad91..82d4e33 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -635,8 +635,7 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
static inline
snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
{
- snd_pcm_uframes_t ptr = runtime->status->hw_ptr;
- return ptr - (ptr % runtime->period_size);
+ return runtime->hw_ptr_interrupt;
}
/* define extended formats in the recent OSS versions (if any) */
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index e2a817e..aa54195 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -325,8 +325,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
if (in_interrupt) {
/* we know that one period was processed */
/* delta = "expected next hw_ptr" for in_interrupt != 0 */
- delta = old_hw_ptr - (old_hw_ptr % runtime->period_size)
- + runtime->period_size;
+ delta = runtime->hw_ptr_interrupt + runtime->period_size;
if (delta > new_hw_ptr) {
hw_base += runtime->buffer_size;
if (hw_base >= runtime->boundary)
@@ -437,6 +436,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
runtime->silence_size > 0)
snd_pcm_playback_silence(substream, new_hw_ptr);
+ if (in_interrupt) {
+ runtime->hw_ptr_interrupt = new_hw_ptr -
+ (new_hw_ptr % runtime->period_size);
+ }
runtime->hw_ptr_base = hw_base;
runtime->status->hw_ptr = new_hw_ptr;
runtime->hw_ptr_jiffies = jiffies;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 56ec35e..7a002db 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1252,6 +1252,8 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
if (err < 0)
return err;
runtime->hw_ptr_base = 0;
+ runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
+ runtime->status->hw_ptr % runtime->period_size;
runtime->silence_start = runtime->status->hw_ptr;
runtime->silence_filled = 0;
return 0;