コード例 #1
0
ファイル: gstalsasink.c プロジェクト: pli3/gst-plugins-base
static guint
gst_alsasink_delay (GstAudioSink * asink)
{
    GstAlsaSink *alsa;
    snd_pcm_sframes_t delay;
    int res;

    alsa = GST_ALSA_SINK (asink);

    GST_DELAY_SINK_LOCK (asink);
    res = snd_pcm_delay (alsa->handle, &delay);
    GST_DELAY_SINK_UNLOCK (asink);
    if (G_UNLIKELY (res < 0)) {
        /* on errors, report 0 delay */
        GST_DEBUG_OBJECT (alsa, "snd_pcm_delay returned %d", res);
        delay = 0;
    }
    if (G_UNLIKELY (delay < 0)) {
        /* make sure we never return a negative delay */
        GST_WARNING_OBJECT (alsa, "snd_pcm_delay returned negative delay");
        delay = 0;
    }

    return delay;
}
コード例 #2
0
int audioStreamer_ALSA::Read(char *buf, int len) // returns 0 if blocked, < 0 if error, > 0 if data
{
	int ret;
	if (m_sleep >= 0)
	{
		struct pollfd pfds[32];
		int cnt=snd_pcm_poll_descriptors(pcm_handle,pfds,32);
		if (cnt>0) poll(pfds,cnt,m_sleep);
	}

	ret=snd_pcm_readi(pcm_handle, buf, len/(m_nch*(m_bps/8)));

	if (ret < 0) 
	{
		if (ret != -EAGAIN) { snd_pcm_prepare(pcm_handle);  }
		return 0;
	}
#if 0
	snd_pcm_sframes_t del=0;
	if (!snd_pcm_delay(pcm_handle,&del) && del > m_bufsize/2 /* JF>used to be /1 */)
	{
		audiostream_onover();
		for (;;) if (snd_pcm_readi(pcm_handle, buf, len/(m_nch*(m_bps/8)))<0) break;
		// we have too many samples, eat some
	}
#endif

	return ret*m_nch*(m_bps/8);
}
コード例 #3
0
int audioStreamer_ALSA::Write(char *buf, int len) // returns 0 on success
{
	snd_pcm_sframes_t del=0;
	if (!len) return 0;

	int cnt=1;
	if (!m_started || !snd_pcm_delay(pcm_handle,&del) && del<1)
	{
		if (m_started) audiostream_onunder();
		else m_started=1;
		cnt=m_nfrags;
    memset(buf,0,len); // reduce noise

	} 

	while (cnt-->0)
	{
		int ret=snd_pcm_writei(pcm_handle, buf, len/(m_nch*(m_bps/8)));
		if (ret < 0)
		{
			if (ret == -EPIPE) snd_pcm_prepare(pcm_handle);
			return 0;
		}
	}

	return 0;
}
コード例 #4
0
static uint64_t
laudio_alsa_get_pos(void)
{
  snd_pcm_sframes_t delay;
  int ret;

  if (pcm_pos == 0)
    return 0;

  if (pcm_last_error != 0)
    return pcm_pos;

  if (snd_pcm_state(hdl) != SND_PCM_STATE_RUNNING)
    return pcm_pos;

  ret = snd_pcm_delay(hdl, &delay);
  if (ret < 0)
    {
      DPRINTF(E_WARN, L_LAUDIO, "Could not obtain PCM delay: %s\n", snd_strerror(ret));

      return pcm_pos;
    }

  return pcm_pos - delay;
}
コード例 #5
0
ファイル: cubeb_alsa.c プロジェクト: captainbrosset/gecko-dev
static int
alsa_stream_get_position(cubeb_stream * stm, uint64_t * position)
{
  snd_pcm_sframes_t delay;

  assert(stm && position);

  pthread_mutex_lock(&stm->mutex);

  delay = -1;
  if (snd_pcm_state(stm->pcm) != SND_PCM_STATE_RUNNING ||
      snd_pcm_delay(stm->pcm, &delay) != 0) {
    *position = stm->last_position;
    pthread_mutex_unlock(&stm->mutex);
    return CUBEB_OK;
  }

  assert(delay >= 0);

  *position = 0;
  if (stm->write_position >= (snd_pcm_uframes_t) delay) {
    *position = stm->write_position - delay;
  }

  stm->last_position = *position;

  pthread_mutex_unlock(&stm->mutex);
  return CUBEB_OK;
}
コード例 #6
0
ファイル: alsa.c プロジェクト: Ichthyostega/Lumiera
size_t
audio_offset()
{
  snd_pcm_delay(playback_handle, &delay);

  return written - delay;
}
コード例 #7
0
ファイル: dsoutput.c プロジェクト: r6144/wine
static void CheckXRUN(IDsDriverBufferImpl* This)
{
    snd_pcm_state_t state = snd_pcm_state(This->pcm);
    snd_pcm_sframes_t delay;
    int err;

    snd_pcm_hwsync(This->pcm);
    snd_pcm_delay(This->pcm, &delay);
    if ( state == SND_PCM_STATE_XRUN )
    {
        err = snd_pcm_prepare(This->pcm);
        CommitAll(This);
        snd_pcm_start(This->pcm);
        WARN("xrun occurred\n");
        if ( err < 0 )
            ERR("recovery from xrun failed, prepare failed: %s\n", snd_strerror(err));
    }
    else if ( state == SND_PCM_STATE_SUSPENDED )
    {
        int err = snd_pcm_resume(This->pcm);
        TRACE("recovery from suspension occurred\n");
        if (err < 0 && err != -EAGAIN){
            err = snd_pcm_prepare(This->pcm);
            if (err < 0)
                ERR("recovery from suspend failed, prepare failed: %s\n", snd_strerror(err));
        }
    } else if ( state != SND_PCM_STATE_RUNNING ) {
        FIXME("Unhandled state: %d\n", state);
    }
}
コード例 #8
0
ファイル: alsa.c プロジェクト: kernelOfTruth/dsp
void alsa_pause(struct codec *c, int p)
{
	struct alsa_state *state = (struct alsa_state *) c->data;
	if (snd_pcm_state(state->dev) != SND_PCM_STATE_PAUSED)
		snd_pcm_delay(state->dev, &state->delay);
	snd_pcm_pause(state->dev, p);
}
コード例 #9
0
ファイル: alsa.c プロジェクト: nihlaeth/read-the-room
static void alsa_close ()
{
	snd_pcm_sframes_t delay;

	assert (handle != NULL);

	/* play what remained in the buffer */
	if (alsa_buf_fill) {
		assert (alsa_buf_fill < chunk_size);

		snd_pcm_format_set_silence (params.format,
				alsa_buf + alsa_buf_fill,
				(chunk_size - alsa_buf_fill) / bytes_per_frame
				* params.channels);
		alsa_buf_fill = chunk_size;
		play_buf_chunks ();
	}

	/* Wait for ALSA buffers to empty.
	 * Do not be tempted to use snd_pcm_nonblock() and snd_pcm_drain()
	 * here; there are two bugs in ALSA which make it a bad idea (see
	 * the SVN commit log for r2550).  Instead we sleep for the duration
	 * of the still unplayed samples. */
	if (snd_pcm_delay (handle, &delay) == 0)
		usleep ((uint64_t) delay * 1000000 / params.rate);
	snd_pcm_close (handle);
	logit ("ALSA device closed");

	params.format = 0;
	params.rate = 0;
	params.channels = 0;
	handle = NULL;
}
コード例 #10
0
ファイル: alsa.c プロジェクト: kernelOfTruth/dsp
ssize_t alsa_delay(struct codec *c)
{
	struct alsa_state *state = (struct alsa_state *) c->data;
	if (snd_pcm_state(state->dev) == SND_PCM_STATE_PAUSED)
		return state->delay;
	snd_pcm_delay(state->dev, &state->delay);
	return state->delay;
}
コード例 #11
0
ファイル: alsa-audio-enc.c プロジェクト: Unhelpful/ffmpeg
static void
audio_get_output_timestamp(AVFormatContext *s1, int stream,
    int64_t *dts, int64_t *wall)
{
    AlsaData *s  = s1->priv_data;
    snd_pcm_sframes_t delay = 0;
    *wall = av_gettime();
    snd_pcm_delay(s->h, &delay);
    *dts = s1->streams[0]->cur_dts - delay;
}
コード例 #12
0
ファイル: alsa.hpp プロジェクト: Themaister/SLIMPlayer
            float delay()
            {
               if (!runnable)
                  return 0.0;

               snd_pcm_sframes_t delay;
               snd_pcm_delay(pcm, &delay);

               return (float)delay / fps;
            }
コード例 #13
0
ファイル: qaudioinput_alsa.cpp プロジェクト: Camelek/qtmoko
qint64 QAudioInputPrivate::bytesAvailable() const
{
    if ( !handle )
        return 0;

    snd_pcm_sframes_t frames;
    if ( snd_pcm_delay( handle, &frames ) < 0 )
        return 0;

    return snd_pcm_frames_to_bytes( handle, frames );
}
コード例 #14
0
ファイル: alsa.c プロジェクト: copernic-us/showtime-1
static int
alsa_audio_deliver(audio_decoder_t *ad, int samples, int64_t pts, int epoch)
{
  decoder_t *d = (decoder_t *)ad;
  media_pipe_t *mp = ad->ad_mp;
  int c;

 retry:
  c = snd_pcm_wait(d->h, 100);
  if(c >= 0) {
    c = snd_pcm_avail_update(d->h);
  }
  if(c == -EPIPE) {
    snd_pcm_prepare(d->h);
    usleep(100000);
    TRACE(TRACE_DEBUG, "ALSA", "Audio underrun");
    d->samples = 0;
    goto retry;
  }

  c = MIN(d->max_frames_per_write, c);

  uint8_t *planes[8] = {0};
  planes[0] = d->tmp;
  c = avresample_read(ad->ad_avr, planes, c);
  
  snd_pcm_status_t *status;
  int err;
  snd_pcm_status_alloca(&status);
  if ((err = snd_pcm_status(d->h, status)) >= 0) {

    if(pts != AV_NOPTS_VALUE) {
      snd_htimestamp_t hts;
      snd_pcm_status_get_trigger_htstamp(status, &hts);
      int64_t ts = hts.tv_sec * 1000000LL + hts.tv_nsec / 1000;
      ts += d->samples * 1000000LL / ad->ad_out_sample_rate;

      hts_mutex_lock(&mp->mp_clock_mutex);
      mp->mp_audio_clock_avtime = ts;
      mp->mp_audio_clock = pts;
      mp->mp_audio_clock_epoch = epoch;
      hts_mutex_unlock(&mp->mp_clock_mutex);
    }
  }

  snd_pcm_sframes_t fr;
  if(!snd_pcm_delay(d->h, &fr))
    ad->ad_delay = 1000000L * fr / ad->ad_out_sample_rate;

  c = snd_pcm_writei(d->h, d->tmp, c);
  d->samples += c;
  return 0;
}
コード例 #15
0
ファイル: alsaspdifsink.c プロジェクト: JJCG/gst-plugins-bad
static snd_pcm_sframes_t
alsaspdifsink_delay (AlsaSPDIFSink * sink)
{
  snd_pcm_sframes_t delay;
  int err;

  err = snd_pcm_delay (sink->pcm, &delay);
  if (err < 0 || delay < 0) {
    return 0;
  }

  return delay;
}
コード例 #16
0
ファイル: tsmf_alsa.c プロジェクト: BUGgs/FreeRDP
static UINT64 tsmf_alsa_get_latency(ITSMFAudioDevice *audio)
{
	UINT64 latency = 0;
	snd_pcm_sframes_t frames = 0;
	TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio;
	if(alsa->out_handle && alsa->actual_rate > 0 &&
			snd_pcm_delay(alsa->out_handle, &frames) == 0 &&
			frames > 0)
	{
		latency = ((UINT64)frames) * 10000000LL / (UINT64) alsa->actual_rate;
	}
	return latency;
}
コード例 #17
0
ファイル: apulse-stream.c プロジェクト: kandeshvari/apulse
APULSE_EXPORT
const pa_timing_info *
pa_stream_get_timing_info(pa_stream *s)
{
    trace_info_f("F %s s=%p\n", __func__, s);

    snd_pcm_sframes_t delay;

    if (snd_pcm_delay(s->ph, &delay) != 0)
        delay = 0;
    s->timing_info.read_index = s->timing_info.write_index - delay * pa_frame_size(&s->ss);

    return &s->timing_info;
}
コード例 #18
0
ファイル: audio_alsa.c プロジェクト: mbedarff/shairport
static long long get_delay(void) {
  snd_pcm_sframes_t frames = 0;
  snd_pcm_delay(alsa_handle, &frames);

  if (frames < 0)
  {
#if SND_LIB_VERSION >= 0x000901 /* snd_pcm_forward() exists since 0.9.0rc8 */
    snd_pcm_forward(alsa_handle, -frames);
#endif
    frames = 0;
  }

  return (long long)(frames * 1000000L / device_sample_rate);
}
コード例 #19
0
ファイル: soundalsa.c プロジェクト: martinpiper/VICE
static int alsa_bufferspace(void)
{
    int err;
    snd_pcm_sframes_t delay;

    if ((err = snd_pcm_delay(handle, &delay)) < 0) {
	if ((err = xrun_recovery(handle, err)) < 0) {
	    log_message(LOG_DEFAULT, "Delay error: %s", snd_strerror(err));
	}
	return alsa_bufsize;
    }

    return alsa_bufsize - delay;
}
コード例 #20
0
ファイル: ordinary_pcm.c プロジェクト: xenyinzen/lx_toolset
/**
 * \brief Obtain delay for a running PCM handle
 * \param pcm ordinary PCM handle
 * \param delayp Returned delay in frames
 * \return 0 on success otherwise a negative error code
 *
 * Delay is distance between current application frame position and
 * sound frame position.
 * It's positive and less than buffer size in normal situation,
 * negative on playback underrun and greater than buffer size on
 * capture overrun.
 */
int sndo_pcm_delay(sndo_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
	int err;
	snd_pcm_sframes_t pdelay, cdelay;

	assert(pcm);
	assert(delayp);
	err = sndo_pcm_check_setup(pcm);
	if (err < 0)
		return err;
	if (pcm->playback)
		err = snd_pcm_avail_update(pcm->playback);
	if (err >= 0 && pcm->capture)
		err = snd_pcm_avail_update(pcm->capture);
	if (err >= 0 && pcm->playback)
		err = snd_pcm_delay(pcm->playback, &pdelay);
	if (err >= 0 && pcm->capture)
		err = snd_pcm_delay(pcm->capture, &cdelay);
	if (pdelay > cdelay)
		pdelay = cdelay;
	*delayp = pdelay;
	return err;
}
コード例 #21
0
/* close the audio device */
int ao_plugin_close(ao_device *device)
{
	ao_alsa_internal *internal;

	if (device) {
          if ((internal = (ao_alsa_internal *) device->internal)) {
            if (internal->pcm_handle) {

              /* this is a PulseAudio ALSA emulation bug workaround;
                 snd_pcm_drain always takes about 2 seconds, even if
                 there's nothing to drain.  Rather than wait for no
                 reason, determine the current playback depth, wait
                 that long, then kill the stream.  Remove this code
                 once Pulse gets fixed. */

              snd_pcm_sframes_t sframes;
              if(snd_pcm_delay (internal->pcm_handle, &sframes)){
                snd_pcm_drain(internal->pcm_handle);
              }else{
                double s = (double)(sframes - internal->static_delay)/internal->sample_rate;
                if(s>1){
                  /* something went wrong; fall back */
                  snd_pcm_drain(internal->pcm_handle);
                }else{
                  if(s>0){
                    struct timespec sleep,wake;
                    sleep.tv_sec = (int)s;
                    sleep.tv_nsec = (s-sleep.tv_sec)*1000000000;
                    while(nanosleep(&sleep,&wake)<0){
                      if(errno==EINTR)
                        sleep=wake;
                      else
                        break;
                    }
                  }
                }
              }
              snd_pcm_close(internal->pcm_handle);
              if(internal->local_config)
                snd_config_delete(internal->local_config);
              internal->local_config=NULL;
              internal->pcm_handle=NULL;
            }
          } else
            awarn("ao_plugin_close called with uninitialized ao_device->internal\n");
	} else
          awarn("ao_plugin_close called with uninitialized ao_device\n");

	return 1;
}
コード例 #22
0
ファイル: cubeb_alsa.c プロジェクト: captainbrosset/gecko-dev
int
alsa_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
{
  snd_pcm_sframes_t delay;
  /* This function returns the delay in frames until a frame written using
     snd_pcm_writei is sent to the DAC. The DAC delay should be < 1ms anyways. */
  if (snd_pcm_delay(stm->pcm, &delay)) {
    return CUBEB_ERROR;
  }

  *latency = delay;

  return CUBEB_OK;
}
コード例 #23
0
/*----------------------------------------------------------------------
|    AlsaOutput_GetStatus
+---------------------------------------------------------------------*/
BLT_METHOD
AlsaOutput_GetStatus(BLT_OutputNode*       _self,
                     BLT_OutputNodeStatus* status)
{
    AlsaOutput*       self = ATX_SELF(AlsaOutput, BLT_OutputNode);
    snd_pcm_status_t* pcm_status;
    snd_pcm_sframes_t delay = 0;
    int               io_result;

    /* default values */
    status->media_time.seconds = 0;
    status->media_time.nanoseconds = 0;
    status->flags = 0;

    /* get the driver status */
    snd_pcm_status_alloca_no_assert(&pcm_status);
    io_result = snd_pcm_status(self->device_handle, pcm_status);
    if (io_result != 0) {
        return BLT_FAILURE;
    }
    delay = snd_pcm_status_get_delay(pcm_status);
    if (delay == 0) {
        /* workaround buggy alsa drivers */
        io_result = snd_pcm_delay(self->device_handle, &delay);
        if (io_result != 0) {
            return BLT_FAILURE;
        }
    }
    
    if (delay > 0 && self->media_type.sample_rate) {
        ATX_UInt64 media_time_samples = (self->next_media_time * 
                                         (ATX_UInt64)self->media_type.sample_rate)/
                                         (ATX_UInt64)1000000000;
        ATX_UInt64 media_time_ns;
        if (delay <= (snd_pcm_sframes_t)media_time_samples) {
            media_time_samples -= delay;
        } else {
            media_time_samples = 0;
        }
        media_time_ns = (media_time_samples*(ATX_UInt64)1000000000)/self->media_type.sample_rate;
        status->media_time = BLT_TimeStamp_FromNanos(media_time_ns);
    } else {
        status->media_time = BLT_TimeStamp_FromNanos(self->next_media_time);
    }
    
    /* return the computed media time */
    ATX_LOG_FINEST_3("delay = %lld samples, input port time = %lld, media time = %lld", (ATX_UInt64)delay, self->next_media_time, BLT_TimeStamp_ToNanos(status->media_time));
    return BLT_SUCCESS;
}
コード例 #24
0
ファイル: pcm-multi-thread.c プロジェクト: Boshin/workspace
static void *peeper(void *data)
{
	int thread_no = (long)data;
	snd_pcm_sframes_t val;
	snd_pcm_status_t *stat;
	snd_htimestamp_t tstamp;
	int mode = running_mode, err;

	snd_pcm_status_alloca(&stat);

	while (running) {
		if (running_mode == MODE_RANDOM)
			mode = rand() % MODE_RANDOM;
		switch (mode) {
		case MODE_AVAIL_UPDATE:
			val = snd_pcm_avail_update(pcm);
			err = 0;
			break;
		case MODE_STATUS:
			err = snd_pcm_status(pcm, stat);
			val = snd_pcm_status_get_avail(stat);
			break;
		case MODE_HWSYNC:
			err = snd_pcm_hwsync(pcm);
			break;
		case MODE_TIMESTAMP:
			err = snd_pcm_htimestamp(pcm, (snd_pcm_uframes_t *)&val,
						 &tstamp);
			break;
		default:
			err = snd_pcm_delay(pcm, &val);
			break;
		}

		if (quiet)
			continue;
		if (running_mode == MODE_RANDOM) {
			fprintf(stderr, "%d%c%s", thread_no, mode_suffix[mode],
				err ? "!" : "");
		} else {
			if (show_value && mode != MODE_HWSYNC)
				fprintf(stderr, "\r%d     ", (int)val);
			else
				fprintf(stderr, "%d%s", thread_no,
					err ? "!" : "");
		}
	}
	return NULL;
}
コード例 #25
0
ファイル: pcm.c プロジェクト: 543872407/Linux_SourceCode
int snd_pcm_avail_delay(snd_pcm_t *pcm,
			snd_pcm_sframes_t *availp,
			snd_pcm_sframes_t *delayp)
{
	int err;
	snd_pcm_sframes_t val;

	err = snd_pcm_delay(pcm, delayp);
	if (err < 0)
		return err;
	val = snd_pcm_avail_update(pcm);
	if (val < 0)
		return (int)val;
	*availp = val;
	return 0;
}
コード例 #26
0
ファイル: pcm_compat.c プロジェクト: asimkadav/fgft
/* static MJR */ int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
				      s32 __user *src)
{
	snd_pcm_sframes_t delay;
	/*mm_segment_t*/ unsigned long fs; // MJR
	int err;

	fs = snd_enter_user();
	err = snd_pcm_delay(substream, &delay);
	snd_leave_user(fs);
	if (err < 0)
		return err;
	if (put_user(delay, src))
		return -EFAULT;
	return err;
}
コード例 #27
0
ファイル: alsa.c プロジェクト: ecthiender/mocp-git
static int alsa_get_buff_fill ()
{
	if (handle) {
		int err;
		snd_pcm_sframes_t delay;
		
		if ((err = snd_pcm_delay(handle, &delay)) < 0) {
			logit ("snd_pcm_delay() failed: %s", snd_strerror(err));
			return 0;
		}

		/* delay can be negative when underrun occur */
		return delay >= 0 ? delay * bytes_per_frame : 0;
	}
	return 0;
}
コード例 #28
0
bool SoundOutput_alsa::is_full()
{
	int rc;
	snd_pcm_sframes_t delay;
	
	if (handle == nullptr) return false;
	
	rc = snd_pcm_delay(handle, &delay);
	if (rc < 0) {
		log_event("debug", "ClanSound: snd_pcm_delay() failed!?");
		return false;
	}

	/* See if there is more then one period free in the buffer */
	return delay > (snd_pcm_sframes_t)(frames_in_buffer - frames_in_period);
}
コード例 #29
0
static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
				      s32 __user *src)
{
	snd_pcm_sframes_t delay;
	mm_segment_t fs;
	int err;

	fs = snd_enter_user();
	err = snd_pcm_delay(substream, &delay);
	snd_leave_user(fs);
	if (err < 0)
		return err;
	if (put_user(delay, src))
		return -EFAULT;
	return err;
}
コード例 #30
0
ファイル: audioalsa.C プロジェクト: ratopi/CinelerraCV
int AudioALSA::write_buffer(char *buffer, int size)
{
// Don't give up and drop the buffer on the first error.
	int attempts = 0;
	int done = 0;
	int samples = size / (device->out_bits / 8) / device->get_ochannels();

	if(!get_output()) return 0;

	while(attempts < 2 && !done && !interrupted)
	{
// Buffers written must be equal to period_time
// Update timing
 		snd_pcm_sframes_t delay;
 		snd_pcm_delay(get_output(), &delay);
		snd_pcm_avail_update(get_output());

		device->Thread::enable_cancel();
		if(snd_pcm_writei(get_output(), 
			buffer, 
			samples) < 0)
		{
			device->Thread::disable_cancel();
			printf("AudioALSA::write_buffer underrun at sample %" PRId64 "\n",
				device->current_position());
//			snd_pcm_resume(get_output());
			close_output();
			open_output();
			attempts++;
		}
		else
		{
			device->Thread::disable_cancel();
			done = 1;
		}
	}

	if(done)
	{
		timer_lock->lock("AudioALSA::write_buffer");
		this->delay = delay;
		timer->update();
		samples_written += samples;
		timer_lock->unlock();
	}
	return 0;
}