diff options
Diffstat (limited to 'sound/core/oss/pcm_oss.c')
-rw-r--r-- | sound/core/oss/pcm_oss.c | 32 |
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 | ||
635 | static inline | ||
636 | snd_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 | ||
1953 | static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) | 1960 | static 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 | ||
2681 | static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) | 2693 | static 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 | ||
2690 | static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) | 2704 | static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) |