static int snd_pcm_dsnoop_drop(snd_pcm_t *pcm) { snd_pcm_direct_t *dsnoop = pcm->private_data; if (dsnoop->state == SND_PCM_STATE_OPEN) return -EBADFD; dsnoop->state = SND_PCM_STATE_SETUP; snd_timer_stop(dsnoop->timer); return 0; }
bool AlsaTimer::stopTimer() { int err; if(TIMER_DEBUG) printf("AlsaTimer::stopTimer(this=%p): handle=%p\n",this,handle); if ((err = snd_timer_stop(handle)) < 0) { fprintf(stderr, "AlsaTimer::stopTimer(): timer stop %i (%s)\n", err, snd_strerror(err)); return false; } return true; }
/* * synchronize hardware pointer (hw_ptr) with ours */ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm) { snd_pcm_direct_t *dshare = pcm->private_data; snd_pcm_uframes_t slave_hw_ptr, old_slave_hw_ptr, avail; snd_pcm_sframes_t diff; switch (snd_pcm_state(dshare->spcm)) { case SND_PCM_STATE_DISCONNECTED: dshare->state = SNDRV_PCM_STATE_DISCONNECTED; return -ENODEV; default: break; } if (dshare->slowptr) snd_pcm_hwsync(dshare->spcm); old_slave_hw_ptr = dshare->slave_hw_ptr; slave_hw_ptr = dshare->slave_hw_ptr = *dshare->spcm->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) { struct timeval tv; snd_timer_stop(dshare->timer); gettimeofday(&tv, 0); dshare->trigger_tstamp.tv_sec = tv.tv_sec; dshare->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; 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; }
/* * synchronize hardware pointer (hw_ptr) with ours */ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm) { snd_pcm_direct_t *dmix = pcm->private_data; snd_pcm_uframes_t slave_hw_ptr, old_slave_hw_ptr, avail; snd_pcm_sframes_t diff; switch (snd_pcm_state(dmix->spcm)) { case SND_PCM_STATE_DISCONNECTED: dmix->state = SND_PCM_STATE_DISCONNECTED; return -ENODEV; default: break; } if (dmix->slowptr) snd_pcm_hwsync(dmix->spcm); old_slave_hw_ptr = dmix->slave_hw_ptr; slave_hw_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; diff = slave_hw_ptr - old_slave_hw_ptr; if (diff == 0) /* fast path */ return 0; if (dmix->state != SND_PCM_STATE_RUNNING && dmix->state != SND_PCM_STATE_DRAINING) /* not really started yet - don't update hw_ptr */ return 0; if (diff < 0) { slave_hw_ptr += dmix->slave_boundary; diff = slave_hw_ptr - old_slave_hw_ptr; } dmix->hw_ptr += diff; dmix->hw_ptr %= pcm->boundary; if (pcm->stop_threshold >= pcm->boundary) /* don't care */ return 0; avail = snd_pcm_mmap_playback_avail(pcm); if (avail > dmix->avail_max) dmix->avail_max = avail; if (avail >= pcm->stop_threshold) { snd_timer_stop(dmix->timer); gettimestamp(&dmix->trigger_tstamp, pcm->tstamp_type); if (dmix->state == SND_PCM_STATE_RUNNING) { dmix->state = SND_PCM_STATE_XRUN; return -EPIPE; } dmix->state = SND_PCM_STATE_SETUP; /* clear queue to remove pending poll events */ snd_pcm_direct_clear_timer_queue(dmix); } return 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; }
static void a2dp_exit(void) { int err, i; err = snd_timer_stop(timer); err = snd_timer_close(timer); a2dp_lock(); for (i = 0; i < MAX_CONNECTIONS; i++) { snd_pcm_a2dp_t *a2dp = connections[i]; if (a2dp) { connections[i] = NULL; a2dp_free(a2dp); } } a2dp_unlock(); }