Пример #1
0
static int audio_close(audiodevice_t *dev) {
	audio_alsa05_t *alsa = (audio_alsa05_t *)dev->data_pcm;
	snd_pcm_channel_status_t st;
	int err, bc;

	dev->fd = -1;
	if (alsa->pcm_handle) {
		memset(&st, 0, sizeof(st));
		if (0 > (err = snd_pcm_channel_status(alsa->pcm_handle, &st))) {
			WARNING("playback status err(%s)\n", snd_strerror(err));
			return snd_pcm_close(alsa->pcm_handle);
		}
		while (st.status == SND_PCM_STATUS_RUNNING) {
			memset(&st, 0, sizeof(st));
			bc = st.count;
			snd_pcm_channel_status(alsa->pcm_handle, &st);
			if (bc == st.count) {
				snd_pcm_channel_flush(alsa->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
			}
			usleep(1000);
		}
		err = snd_pcm_close(alsa->pcm_handle);
		alsa->pcm_handle = NULL;
		return err;
	} else {
		return OK;
	}
}
Пример #2
0
void AlsaPMO::HandleTimeInfoEvent(PMOTimeInfoEvent *pEvent)
{
   MediaTimeInfoEvent *pmtpi;
   int32               hours, minutes, seconds;
   int                 iTotalTime = 0;
   snd_pcm_channel_status_t ainfo;

   if (m_iBaseTime < 0)
   {
       m_iBaseTime = (pEvent->GetFrameNumber() * 
                      myInfo->samples_per_frame) / 
                      myInfo->samples_per_second;
   }

   ainfo.channel = SND_PCM_CHANNEL_PLAYBACK;
   snd_pcm_channel_status(m_handle,&ainfo);

   iTotalTime = ainfo.scount / (m_iBytesPerSample * myInfo->samples_per_second);
   iTotalTime = (iTotalTime + m_iBaseTime) % 86400;

   hours = iTotalTime / 3600;
   minutes = (iTotalTime / 60) % 60;
   seconds = iTotalTime % 60;

   if (hours < 0  ||
       minutes < 0 || minutes > 59 || 
       seconds < 0 || seconds > 59)
      return;

   pmtpi = new MediaTimeInfoEvent(hours, minutes, seconds, 0, 
                                  iTotalTime, 0);
   m_pTarget->AcceptEvent(pmtpi);
}
Пример #3
0
static int audio_write(audiodevice_t *dev, unsigned char *buf, int cnt) {
	audio_alsa05_t *alsa = (audio_alsa05_t *)dev->data_pcm;
	snd_pcm_channel_status_t st;
	int ret;
	
	if (alsa->pcm_handle == NULL) return NG;
	
	if (cnt == 0) return 0;
	
	if (cnt < dev->buf.len) {
		memset(buf + cnt, alsa->silence, dev->buf.len - cnt);
	}
	
	memset(&st, 0, sizeof(st));
	if (0 > (ret = snd_pcm_channel_status(alsa->pcm_handle, &st))) {
		WARNING("cannot get status %s\n", snd_strerror(ret));
		return 0;
	}
	
	if (st.status != SND_PCM_STATUS_RUNNING &&
	    st.status != SND_PCM_STATUS_PREPARED) {
		snd_pcm_channel_prepare(alsa->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
	}
	
	ret = snd_pcm_write(alsa->pcm_handle, buf, dev->buf.len);
	if (ret < 0) {
		WARNING("write %s\n", snd_strerror(ret));
	}
	
	return dev->buf.len;
}
Пример #4
0
static int check_pcm_status(void *data, int channel_type)
{
   snd_pcm_channel_status_t status;
   alsa_t *alsa = (alsa_t*)data;
   int ret      = EOK;

   memset(&status, 0, sizeof (status));
   status.channel = channel_type;

   if ((ret = snd_pcm_channel_status(alsa->pcm, &status)) == 0)
   {
      if (status.status == SND_PCM_STATUS_UNSECURE)
      {
         RARCH_ERR("check_pcm_status got SND_PCM_STATUS_UNSECURE, aborting playback\n");
         ret = -EPROTO;
      }
      else if (status.status == SND_PCM_STATUS_UNDERRUN)
      {
         RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_UNDERRUN.\n");
         if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
         {
            RARCH_ERR("Invalid state detected for underrun on snd_pcm_channel_prepare: %s\n",
                  snd_strerror(ret));
            ret = -EPROTO;
         }
      }
      else if (status.status == SND_PCM_STATUS_OVERRUN)
      {
         RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_OVERRUN.\n");
         if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
         {
            RARCH_ERR("Invalid state detected for overrun on snd_pcm_channel_prepare: %s\n",
                  snd_strerror(ret));
            ret = -EPROTO;
         }
      }
      else if (status.status == SND_PCM_STATUS_CHANGE)
      {
         RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_CHANGE.\n");
         if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
         {
            RARCH_ERR("Invalid state detected for change on snd_pcm_channel_prepare: %s\n",
                  snd_strerror(ret));
            ret = -EPROTO;
         }
      }
   }
   else
   {
      RARCH_ERR("check_pcm_status failed: %s\n", snd_strerror(ret));
      if (ret == -ESRCH)
         ret = -EBADF;
   }

   return ret;
}
Пример #5
0
/* delay in seconds between first and last sample in buffer */
static float get_delay(void)
{
    snd_pcm_channel_status_t ch_stat;

    ch_stat.channel = SND_PCM_CHANNEL_PLAYBACK;

    if (snd_pcm_channel_status(alsa_handler, &ch_stat) < 0)
	return (float)ao_data.buffersize/(float)ao_data.bps; /* error occurred */
    else
	return (float)ch_stat.count/(float)ao_data.bps;
}
Пример #6
0
/* how many byes are free in the buffer */
static int get_space(void)
{
    snd_pcm_channel_status_t ch_stat;

    ch_stat.channel = SND_PCM_CHANNEL_PLAYBACK;

    if (snd_pcm_channel_status(alsa_handler, &ch_stat) < 0)
	return 0; /* error occurred */
    else
	return ch_stat.free;
}
Пример #7
0
int _alsa_write_buffer(ao_alsa_internal *s)
{
	snd_pcm_channel_status_t status;
	snd_pcm_t *pcm_handle = s->pcm_handle;
	int len = s->buf_end;
	ssize_t written, snd_pcm_write_ret;

	s->buf_end = 0;

	snd_pcm_write_ret = written = 0;
	while ((snd_pcm_write_ret >= 0) && (written < len)) {
		while ((snd_pcm_write_ret = snd_pcm_write(pcm_handle, s->buf, len)) == -EINTR)
			;
		if (snd_pcm_write_ret > 0)
			written += snd_pcm_write_ret;
	}

	memset(&status, 0, sizeof(status));
	if (snd_pcm_channel_status(pcm_handle, &status) < 0) {
		fprintf(stderr, "ALSA: could not get channel status\n");
		return 0;
	}       
	if (status.underrun) {
		/* fprintf(stderr, "ALSA: underrun. resetting channel\n"); */
		snd_pcm_channel_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
		snd_pcm_playback_prepare(pcm_handle);
		snd_pcm_write(pcm_handle, s->buf, len);
		if (snd_pcm_channel_status(pcm_handle, &status) < 0) {
			fprintf(stderr, "ALSA: could not get channel status. giving up\n");
			return 0;
		}
		if (status.underrun) {
			fprintf(stderr, "ALSA: write error. giving up\n");
					return 0;
		}               
	}

	return 1;
}	
Пример #8
0
bool AlsaPMO::WaitForDrain(void)
{
   snd_pcm_channel_status_t ainfo;

   for(; !m_bExit && !m_bPause; )
   {
       ainfo.channel = SND_PCM_CHANNEL_PLAYBACK;
       snd_pcm_channel_status(m_handle,&ainfo);

       if (ainfo.underrun || ainfo.status == SND_PCM_STATUS_UNDERRUN)
       {
           return true;
       }
       WasteTime();
   }

   return false;
}