Exemplo n.º 1
0
static int snd_pcm_dshare_drop(snd_pcm_t *pcm)
{
	snd_pcm_direct_t *dshare = pcm->private_data;
	if (dshare->state == SND_PCM_STATE_OPEN)
		return -EBADFD;
	snd_pcm_direct_timer_stop(dshare);
	do_silence(pcm);
	dshare->state = SND_PCM_STATE_SETUP;
	return 0;
}
Exemplo n.º 2
0
/*
 *  synchronize hardware pointer (hw_ptr) with ours
 */
static int snd_pcm_dshare_sync_ptr0(snd_pcm_t *pcm, snd_pcm_uframes_t slave_hw_ptr)
{
	snd_pcm_direct_t *dshare = pcm->private_data;
	snd_pcm_uframes_t old_slave_hw_ptr, avail;
	snd_pcm_sframes_t diff;
	
	old_slave_hw_ptr = dshare->slave_hw_ptr;
	dshare->slave_hw_ptr = slave_hw_ptr;
	diff = slave_hw_ptr - old_slave_hw_ptr;
	if (diff == 0)		/* fast path */
		return 0;
	if (dshare->state != SND_PCM_STATE_RUNNING &&
	    dshare->state != SND_PCM_STATE_DRAINING)
		/* not really started yet - don't update hw_ptr */
		return 0;
	if (diff < 0) {
		slave_hw_ptr += dshare->slave_boundary;
		diff = slave_hw_ptr - old_slave_hw_ptr;
	}
	dshare->hw_ptr += diff;
	dshare->hw_ptr %= pcm->boundary;
	// printf("sync ptr diff = %li\n", diff);
	if (pcm->stop_threshold >= pcm->boundary)	/* don't care */
		return 0;
	avail = snd_pcm_mmap_playback_avail(pcm);
	if (avail > dshare->avail_max)
		dshare->avail_max = avail;
	if (avail >= pcm->stop_threshold) {
		snd_timer_stop(dshare->timer);
		do_silence(pcm);
		gettimestamp(&dshare->trigger_tstamp, pcm->tstamp_type);
		if (dshare->state == SND_PCM_STATE_RUNNING) {
			dshare->state = SND_PCM_STATE_XRUN;
			return -EPIPE;
		}
		dshare->state = SND_PCM_STATE_SETUP;
		/* clear queue to remove pending poll events */
		snd_pcm_direct_clear_timer_queue(dshare);
	}
	return 0;
}