--- aloop-kernel-orig.c 2008-02-19 03:27:10.203115360 +0100 +++ aloop-kernel.c 2008-02-19 03:23:56.874121702 +0100 @@ -32,9 +32,6 @@ /* comment in to trash your kernel logfiles */ /* #define SND_CARD_LOOPBACK_VERBOSE */ -/* comment in for synchronization on start trigger - * works well on alsa apps but bad on oss emulation */ -/* #define SND_CARD_LOOPBACK_START_SYNC */ MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("A loopback soundcard"); @@ -85,16 +82,13 @@ snd_card_loopback_t *loopback; spinlock_t lock; struct timer_list timer; - int stream; - unsigned int pcm_1000_size; - unsigned int pcm_1000_count; - unsigned int pcm_size; - unsigned int pcm_count; + unsigned int pcm_size_hz; + unsigned int pcm_count_hz; unsigned int pcm_bps; /* bytes per second */ - unsigned int pcm_1000_jiffie; /* 1000 * bytes per one jiffie */ - unsigned int pcm_1000_irq_pos; /* IRQ position */ - unsigned int pcm_1000_buf_pos; /* position in buffer */ - unsigned int pcm_period_pos; /* period aligned pos in buffer */ + unsigned int pcm_hz; /* HZ */ + unsigned int pcm_irq_pos_hz; /* IRQ position * HZ */ + unsigned int pcm_buf_pos_hz; /* position in buffer * HZ */ + unsigned int pcm_period_pos_hz; /* period aligned pos in buffer * HZ */ struct snd_pcm_substream *substream; struct snd_card_loopback_cable *cable; } snd_card_loopback_pcm_t; @@ -123,18 +117,7 @@ { struct snd_pcm_runtime *runtime = substream->runtime; snd_card_loopback_pcm_t *dpcm = runtime->private_data; -#ifdef SND_CARD_LOOPBACK_START_SYNC - snd_card_loopback_pcm_t *capture_dpcm; -#endif if (cmd == SNDRV_PCM_TRIGGER_START) { -#ifdef SND_CARD_LOOPBACK_START_SYNC - if (dpcm->cable->capture_running) { - capture_dpcm = dpcm->cable->capture->runtime->private_data; - dpcm->pcm_1000_irq_pos = capture_dpcm->pcm_1000_irq_pos; - dpcm->pcm_1000_buf_pos = capture_dpcm->pcm_1000_buf_pos; - dpcm->pcm_period_pos = capture_dpcm->pcm_period_pos; - } -#endif dpcm->cable->playback_running = 1; snd_card_loopback_timer_start(substream); } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { @@ -154,18 +137,7 @@ { struct snd_pcm_runtime *runtime = substream->runtime; snd_card_loopback_pcm_t *dpcm = runtime->private_data; -#ifdef SND_CARD_LOOPBACK_START_SYNC - snd_card_loopback_pcm_t *playback_dpcm; -#endif if (cmd == SNDRV_PCM_TRIGGER_START) { -#ifdef SND_CARD_LOOPBACK_START_SYNC - if (dpcm->cable->playback_running) { - playback_dpcm = dpcm->cable->playback->runtime->private_data; - dpcm->pcm_1000_irq_pos = playback_dpcm->pcm_1000_irq_pos; - dpcm->pcm_1000_buf_pos = playback_dpcm->pcm_1000_buf_pos; - dpcm->pcm_period_pos = playback_dpcm->pcm_period_pos; - } -#endif dpcm->cable->capture_running = 1; snd_card_loopback_timer_start(substream); } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { @@ -190,14 +162,12 @@ if (bps <= 0) return -EINVAL; dpcm->pcm_bps = bps; - dpcm->pcm_1000_jiffie = (1000 * bps) / HZ; - dpcm->pcm_size = frames_to_bytes(runtime, runtime->buffer_size); - dpcm->pcm_count = frames_to_bytes(runtime, runtime->period_size); - dpcm->pcm_1000_size = 1000 * frames_to_bytes(runtime, runtime->buffer_size); - dpcm->pcm_1000_count = 1000 * frames_to_bytes(runtime, runtime->period_size); - dpcm->pcm_1000_irq_pos = 0; - dpcm->pcm_1000_buf_pos = 0; - dpcm->pcm_period_pos = 0; + dpcm->pcm_hz = HZ; + dpcm->pcm_size_hz = frames_to_bytes(runtime, runtime->buffer_size) * dpcm->pcm_hz; + dpcm->pcm_count_hz = frames_to_bytes(runtime, runtime->period_size) * dpcm->pcm_hz; + dpcm->pcm_irq_pos_hz = 0; + dpcm->pcm_buf_pos_hz = 0; + dpcm->pcm_period_pos_hz = 0; cable->hw.formats = (1ULL << runtime->format); cable->hw.rate_min = runtime->rate; @@ -246,13 +216,13 @@ add_timer(&dpcm->timer); spin_lock_irq(&dpcm->lock); - dpcm->pcm_1000_irq_pos += dpcm->pcm_1000_jiffie; - dpcm->pcm_1000_buf_pos += dpcm->pcm_1000_jiffie; - dpcm->pcm_1000_buf_pos %= dpcm->pcm_1000_size; - if (dpcm->pcm_1000_irq_pos >= dpcm->pcm_1000_count) { - dpcm->pcm_1000_irq_pos %= dpcm->pcm_1000_count; - dpcm->pcm_period_pos += dpcm->pcm_count; - dpcm->pcm_period_pos %= dpcm->pcm_size; + dpcm->pcm_irq_pos_hz += dpcm->pcm_bps; + dpcm->pcm_buf_pos_hz += dpcm->pcm_bps; + dpcm->pcm_buf_pos_hz %= dpcm->pcm_size_hz; + if (dpcm->pcm_irq_pos_hz >= dpcm->pcm_count_hz) { + dpcm->pcm_irq_pos_hz %= dpcm->pcm_count_hz; + dpcm->pcm_period_pos_hz += dpcm->pcm_count_hz; + dpcm->pcm_period_pos_hz %= dpcm->pcm_size_hz; spin_unlock_irq(&dpcm->lock); snd_pcm_period_elapsed(dpcm->substream); } else { @@ -264,7 +234,7 @@ { struct snd_pcm_runtime *runtime = substream->runtime; snd_card_loopback_pcm_t *dpcm = runtime->private_data; - return bytes_to_frames(runtime, dpcm->pcm_period_pos); + return bytes_to_frames(runtime, dpcm->pcm_period_pos_hz / dpcm->pcm_hz); } static struct snd_pcm_hardware snd_card_loopback_info = @@ -381,7 +351,6 @@ dpcm->timer.data = (unsigned long)dpcm; dpcm->timer.function = snd_card_loopback_timer_function; dpcm->cable = &loopback->cables[substream->number][half]; - dpcm->stream = substream->stream; runtime->private_data = dpcm; runtime->private_free = snd_card_loopback_runtime_free; runtime->hw = snd_card_loopback_info;