예제 #1
0
파일: minivosc.c 프로젝트: bluegum/maxivosc
static int minivosc_pcm_prepare(struct snd_pcm_substream *ss)
{
	// copied from aloop-kernel.c

	// for one, we could get mydev from ss->private_data...
	// here we try it via ss->runtime->private_data instead.
	// turns out, this type of call via runtime->private_data
	// ends up with mydev as null pointer causing SIGSEGV
	// .. UNLESS runtime->private_data is assigned in _open?
	struct snd_pcm_runtime *runtime = ss->runtime;
	struct minivosc_device *mydev = runtime->private_data;
	unsigned int bps;

	dbg("%s", __func__);

	bps = runtime->rate * runtime->channels; // params requested by user app (arecord, audacity)
	bps *= snd_pcm_format_width(runtime->format);
	bps /= 8;
	if (bps <= 0)
		return -EINVAL;

	mydev->buf_pos = 0;
	mydev->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
	dbg2("	bps: %u; runtime->buffer_size: %lu; mydev->pcm_buffer_size: %u", bps, runtime->buffer_size, mydev->pcm_buffer_size);
	if (ss->stream == SNDRV_PCM_STREAM_CAPTURE) {
		/* clear capture buffer */
		mydev->silent_size = mydev->pcm_buffer_size;
		//memset(runtime->dma_area, 0, mydev->pcm_buffer_size);
		// we're in char land here, so let's mark prepare buffer with value 45 (signature)
		// this turns out to set everything permanently throughout - not just first buffer,
		// even though it runs only at start?
		memset(runtime->dma_area, 45, mydev->pcm_buffer_size);
	}

	if (!mydev->running) {
		mydev->irq_pos = 0;
		mydev->period_update_pending = 0;
	}


	mutex_lock(&mydev->cable_lock);
	if (!(mydev->valid & ~(1 << ss->stream))) {
		mydev->pcm_bps = bps;
		mydev->pcm_period_size =
			frames_to_bytes(runtime, runtime->period_size);
		mydev->period_size_frac = frac_pos(mydev->pcm_period_size);

	}
	mydev->valid |= 1 << ss->stream;
	mutex_unlock(&mydev->cable_lock);

	dbg2("	pcm_period_size: %u; period_size_frac: %u", mydev->pcm_period_size, mydev->period_size_frac);

	return 0;
}
예제 #2
0
파일: aloop.c 프로젝트: 19Dan01/linux
/* call in cable->lock */
static void loopback_timer_start(struct loopback_pcm *dpcm)
{
	unsigned long tick;
	unsigned int rate_shift = get_rate_shift(dpcm);

	if (rate_shift != dpcm->pcm_rate_shift) {
		dpcm->pcm_rate_shift = rate_shift;
		dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
	}
	if (dpcm->period_size_frac <= dpcm->irq_pos) {
		dpcm->irq_pos %= dpcm->period_size_frac;
		dpcm->period_update_pending = 1;
	}
	tick = dpcm->period_size_frac - dpcm->irq_pos;
	tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
	mod_timer(&dpcm->timer, jiffies + tick);
}