*参照元 [#g0dd336b] #backlinks *説明 [#j0b6bf5d] -パス: [[linux-2.6.33/sound/core/pcm_lib.c]] -FIXME: これは何? --説明 **引数 [#yc6336d0] -struct snd_pcm_substream *substream -- --[[linux-2.6.33/snd_pcm_substream]] **返り値 [#te2d64ed] -int -- **参考 [#ge704c1b] *実装 [#l9a7cc6f] /* CAUTION: call it with irq disabled */ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t pos; snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base; snd_pcm_sframes_t delta; unsigned long jdelta; - --[[linux-2.6.33/snd_pcm_runtime]] - --[[linux-2.6.33/snd_pcm_uframes_t]] - --[[linux-2.6.33/snd_pcm_sframes_t]] old_hw_ptr = runtime->status->hw_ptr; pos = snd_pcm_update_hw_ptr_pos(substream, runtime); if (pos == SNDRV_PCM_POS_XRUN) { xrun(substream); return -EPIPE; } -runtime->status は snd_pcm_mmap_status 型のメンバ。 --[[linux-2.6.33/snd_pcm_mmap_status]] - --[[linux-2.6.33/snd_pcm_update_hw_ptr_pos()]] - --[[linux-2.6.33/SNDRV_PCM_POS_XRUN]] - --[[linux-2.6.33/xrun()]] if (xrun_debug(substream, 16)) { char name[16]; pcm_debug_name(substream, name, sizeof(name)); snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, " "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", name, (unsigned int)pos, (unsigned int)runtime->period_size, (unsigned int)runtime->buffer_size, (unsigned long)old_hw_ptr, (unsigned long)runtime->hw_ptr_base, (unsigned long)runtime->hw_ptr_interrupt); } - --[[linux-2.6.33/xrun_debug()]] - --[[linux-2.6.33/pcm_debug_name()]] - --[[linux-2.6.33/snd_printd()]] hw_base = runtime->hw_ptr_base; new_hw_ptr = hw_base + pos; delta = new_hw_ptr - old_hw_ptr; jdelta = jiffies - runtime->hw_ptr_jiffies; if (delta < 0) { delta += runtime->buffer_size; if (delta < 0) { hw_ptr_error(substream, "Unexpected hw_pointer value [2] " "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n", substream->stream, (long)pos, (long)old_hw_ptr, jdelta); return 0; } hw_base += runtime->buffer_size; if (hw_base >= runtime->boundary) hw_base = 0; new_hw_ptr = hw_base + pos; } - --[[linux-2.6.33/hw_ptr_error()]] /* Do jiffies check only in xrun_debug mode */ if (!xrun_debug(substream, 4)) goto no_jiffies_check; if (delta < runtime->delay) goto no_jiffies_check; delta -= runtime->delay; if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) { hw_ptr_error(substream, "hw_ptr skipping! " "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n", (long)pos, (long)delta, (long)runtime->period_size, jdelta, ((delta * HZ) / runtime->rate)); return 0; } no_jiffies_check: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); - --[[linux-2.6.33/SNDRV_PCM_STREAM_PLAYBACK]] - --[[linux-2.6.33/snd_pcm_playback_silence()]] if (runtime->status->hw_ptr == new_hw_ptr) return 0; runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; runtime->hw_ptr_jiffies = jiffies; if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); - --[[linux-2.6.33/SNDRV_PCM_TSTAMP_ENABLE]] - --[[linux-2.6.33/snd_pcm_gettime()]] return snd_pcm_update_hw_ptr_post(substream, runtime); - --[[linux-2.6.33/snd_pcm_update_hw_ptr_post()]] } *コメント [#tba5e64d]