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; } }
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); }
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; }
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; }
/* 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; }
/* 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; }
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; }
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; }