diff options
author | Markus Bollinger <bollinger@digigram.com> | 2012-06-20 02:32:48 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-06-20 02:35:28 -0400 |
commit | d7dc9e32ae64b5db777017344da61a285c2347f8 (patch) | |
tree | 2f06b4dade77082cefce0f06491f12d5bfbd692c | |
parent | e0815f35ccd276a903298ad4c3d8d10b65933b86 (diff) |
ALSA: pcxhr: Fix a counter wrap
fix a counter wrap to avoid resynchronization of stream positions every several
minutes. The resynchronization may create stream position jitter
Signed-off-by: Markus Bollinger <bollinger@digigram.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/pcxhr/pcxhr_core.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 304411c1fe4..841703b5c52 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c | |||
@@ -1133,13 +1133,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr, | |||
1133 | hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; | 1133 | hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; |
1134 | hw_sample_count += (u_int64_t)rmh.stat[1]; | 1134 | hw_sample_count += (u_int64_t)rmh.stat[1]; |
1135 | 1135 | ||
1136 | snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", | 1136 | snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n", |
1137 | stream->pipe->is_capture ? 'C' : 'P', | 1137 | stream->pipe->is_capture ? 'C' : 'P', |
1138 | stream->substream->number, | 1138 | stream->substream->number, |
1139 | (long unsigned int)hw_sample_count, | 1139 | hw_sample_count, |
1140 | (long unsigned int)(stream->timer_abs_periods + | 1140 | stream->timer_abs_periods + stream->timer_period_frag + |
1141 | stream->timer_period_frag + | 1141 | mgr->granularity); |
1142 | mgr->granularity)); | ||
1143 | return hw_sample_count; | 1142 | return hw_sample_count; |
1144 | } | 1143 | } |
1145 | 1144 | ||
@@ -1243,10 +1242,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) | |||
1243 | 1242 | ||
1244 | if ((dsp_time_diff < 0) && | 1243 | if ((dsp_time_diff < 0) && |
1245 | (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { | 1244 | (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { |
1246 | snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " | 1245 | /* handle dsp counter wraparound without resync */ |
1247 | "resynchronize all streams\n", | 1246 | int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1; |
1247 | snd_printdd("WARNING DSP timestamp old(%d) new(%d)", | ||
1248 | mgr->dsp_time_last, dsp_time_new); | 1248 | mgr->dsp_time_last, dsp_time_new); |
1249 | mgr->dsp_time_err++; | 1249 | if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) { |
1250 | snd_printdd("-> timestamp wraparound OK: " | ||
1251 | "diff=%d\n", tmp_diff); | ||
1252 | dsp_time_diff = tmp_diff; | ||
1253 | } else { | ||
1254 | snd_printdd("-> resynchronize all streams\n"); | ||
1255 | mgr->dsp_time_err++; | ||
1256 | } | ||
1250 | } | 1257 | } |
1251 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1258 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1252 | if (dsp_time_diff == 0) | 1259 | if (dsp_time_diff == 0) |