aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/oss/pcm_oss.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/oss/pcm_oss.c')
-rw-r--r--sound/core/oss/pcm_oss.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c96353121a..255ad910077a 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -632,6 +632,13 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); 632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
633} 633}
634 634
635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{
638 snd_pcm_uframes_t ptr = runtime->status->hw_ptr;
639 return ptr - (ptr % runtime->period_size);
640}
641
635/* define extended formats in the recent OSS versions (if any) */ 642/* define extended formats in the recent OSS versions (if any) */
636/* linear formats */ 643/* linear formats */
637#define AFMT_S32_LE 0x00001000 644#define AFMT_S32_LE 0x00001000
@@ -1102,7 +1109,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1102 return err; 1109 return err;
1103 } 1110 }
1104 runtime->oss.prepare = 0; 1111 runtime->oss.prepare = 0;
1105 runtime->oss.prev_hw_ptr_interrupt = 0; 1112 runtime->oss.prev_hw_ptr_period = 0;
1106 runtime->oss.period_ptr = 0; 1113 runtime->oss.period_ptr = 0;
1107 runtime->oss.buffer_used = 0; 1114 runtime->oss.buffer_used = 0;
1108 1115
@@ -1950,7 +1957,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1950 return result; 1957 return result;
1951} 1958}
1952 1959
1953static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) 1960static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1961 snd_pcm_uframes_t hw_ptr)
1954{ 1962{
1955 struct snd_pcm_runtime *runtime = substream->runtime; 1963 struct snd_pcm_runtime *runtime = substream->runtime;
1956 snd_pcm_uframes_t appl_ptr; 1964 snd_pcm_uframes_t appl_ptr;
@@ -1986,7 +1994,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1986 if (runtime->oss.trigger) 1994 if (runtime->oss.trigger)
1987 goto _skip1; 1995 goto _skip1;
1988 if (atomic_read(&psubstream->mmap_count)) 1996 if (atomic_read(&psubstream->mmap_count))
1989 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1997 snd_pcm_oss_simulate_fill(psubstream,
1998 get_hw_ptr_period(runtime));
1990 runtime->oss.trigger = 1; 1999 runtime->oss.trigger = 1;
1991 runtime->start_threshold = 1; 2000 runtime->start_threshold = 1;
1992 cmd = SNDRV_PCM_IOCTL_START; 2001 cmd = SNDRV_PCM_IOCTL_START;
@@ -2105,11 +2114,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
2105 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2114 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2106 if (atomic_read(&substream->mmap_count)) { 2115 if (atomic_read(&substream->mmap_count)) {
2107 snd_pcm_sframes_t n; 2116 snd_pcm_sframes_t n;
2108 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2117 delay = get_hw_ptr_period(runtime);
2118 n = delay - runtime->oss.prev_hw_ptr_period;
2109 if (n < 0) 2119 if (n < 0)
2110 n += runtime->boundary; 2120 n += runtime->boundary;
2111 info.blocks = n / runtime->period_size; 2121 info.blocks = n / runtime->period_size;
2112 runtime->oss.prev_hw_ptr_interrupt = delay; 2122 runtime->oss.prev_hw_ptr_period = delay;
2113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2123 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2114 snd_pcm_oss_simulate_fill(substream, delay); 2124 snd_pcm_oss_simulate_fill(substream, delay);
2115 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; 2125 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
@@ -2673,18 +2683,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2673{ 2683{
2674 struct snd_pcm_runtime *runtime = substream->runtime; 2684 struct snd_pcm_runtime *runtime = substream->runtime;
2675 if (atomic_read(&substream->mmap_count)) 2685 if (atomic_read(&substream->mmap_count))
2676 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2686 return runtime->oss.prev_hw_ptr_period !=
2687 get_hw_ptr_period(runtime);
2677 else 2688 else
2678 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2689 return snd_pcm_playback_avail(runtime) >=
2690 runtime->oss.period_frames;
2679} 2691}
2680 2692
2681static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2693static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2682{ 2694{
2683 struct snd_pcm_runtime *runtime = substream->runtime; 2695 struct snd_pcm_runtime *runtime = substream->runtime;
2684 if (atomic_read(&substream->mmap_count)) 2696 if (atomic_read(&substream->mmap_count))
2685 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2697 return runtime->oss.prev_hw_ptr_period !=
2698 get_hw_ptr_period(runtime);
2686 else 2699 else
2687 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2700 return snd_pcm_capture_avail(runtime) >=
2701 runtime->oss.period_frames;
2688} 2702}
2689 2703
2690static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) 2704static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)