static void CheckXRUN(IDsCaptureDriverBufferImpl* 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, FALSE); 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) { WARN("Unhandled state: %d\n", state); } }
int QAudioInputPrivate::xrun_recovery(int err) { int count = 0; bool reset = false; if(err == -EPIPE) { errorState = QAudio::UnderrunError; err = snd_pcm_prepare(handle); if(err < 0) reset = true; } else if((err == -ESTRPIPE)||(err == -EIO)) { errorState = QAudio::IOError; while((err = snd_pcm_resume(handle)) == -EAGAIN){ usleep(100); count++; if(count > 5) { reset = true; break; } } if(err < 0) { err = snd_pcm_prepare(handle); if(err < 0) reset = true; } } if(reset) { close(); open(); snd_pcm_prepare(handle); return 0; } return err; }
void CAESinkALSA::HandleError(const char* name, int err) { switch(err) { case -EPIPE: CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - underrun", name); if ((err = snd_pcm_prepare(m_pcm)) < 0) CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - snd_pcm_prepare returned %d (%s)", name, err, snd_strerror(err)); break; case -ESTRPIPE: CLog::Log(LOGINFO, "CAESinkALSA::HandleError(%s) - Resuming after suspend", name); /* try to resume the stream */ while((err = snd_pcm_resume(m_pcm)) == -EAGAIN) Sleep(1); /* if the hardware doesnt support resume, prepare the stream */ if (err == -ENOSYS) if ((err = snd_pcm_prepare(m_pcm)) < 0) CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - snd_pcm_prepare returned %d (%s)", name, err, snd_strerror(err)); break; default: CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - snd_pcm_writei returned %d (%s)", name, err, snd_strerror(err)); break; } }
int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent) { if (err > 0) err = -err; if (err == -EINTR) /* nothing to do, continue */ return 0; if (err == -EPIPE) { err = snd_pcm_prepare(pcm); if (err < 0) return err; return 0; } if (err == -ESTRPIPE) { while ((err = snd_pcm_resume(pcm)) == -EAGAIN) /* wait until suspend flag is released */ poll(NULL, 0, 1000); if (err < 0) { err = snd_pcm_prepare(pcm); if (err < 0) return err; } return 0; } return err; }
/* * Underrun and suspend recovery */ static gint xrun_recovery (GstAlsaSink * alsa, snd_pcm_t * handle, gint err) { GST_WARNING_OBJECT (alsa, "xrun recovery %d: %s", err, g_strerror (-err)); if (err == -EPIPE) { /* under-run */ err = snd_pcm_prepare (handle); if (err < 0) GST_WARNING_OBJECT (alsa, "Can't recover from underrun, prepare failed: %s", snd_strerror (err)); gst_audio_base_sink_report_device_failure (GST_AUDIO_BASE_SINK (alsa)); return 0; } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume (handle)) == -EAGAIN) g_usleep (100); /* wait until the suspend flag is released */ if (err < 0) { err = snd_pcm_prepare (handle); if (err < 0) GST_WARNING_OBJECT (alsa, "Can't recover from suspend, prepare failed: %s", snd_strerror (err)); } if (err == 0) gst_audio_base_sink_report_device_failure (GST_AUDIO_BASE_SINK (alsa)); return 0; } return err; }
/* * Underrun and suspend recovery */ static gint xrun_recovery (GstAlsaSink * alsa, snd_pcm_t * handle, gint err) { GST_DEBUG_OBJECT (alsa, "xrun recovery %d", err); if (err == -EPIPE) { /* under-run */ err = snd_pcm_prepare (handle); if (err < 0) GST_WARNING_OBJECT (alsa, "Can't recovery from underrun, prepare failed: %s", snd_strerror (err)); return 0; } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume (handle)) == -EAGAIN) g_usleep (100); /* wait until the suspend flag is released */ if (err < 0) { err = snd_pcm_prepare (handle); if (err < 0) GST_WARNING_OBJECT (alsa, "Can't recovery from suspend, prepare failed: %s", snd_strerror (err)); } return 0; } return err; }
int DAUDIO_Start(void* id, int isSource) { AlsaPcmInfo* info = (AlsaPcmInfo*) id; int ret; snd_pcm_state_t state; TRACE0("> DAUDIO_Start\n"); // set to blocking mode snd_pcm_nonblock(info->handle, 0); // set start mode so that it always starts as soon as data is there setStartThreshold(info, TRUE /* use threshold */); state = snd_pcm_state(info->handle); if (state == SND_PCM_STATE_PAUSED) { // in case it was stopped previously TRACE0(" Un-pausing...\n"); ret = snd_pcm_pause(info->handle, FALSE); if (ret != 0) { ERROR2(" NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret)); } } if (state == SND_PCM_STATE_SUSPENDED) { TRACE0(" Resuming...\n"); ret = snd_pcm_resume(info->handle); if (ret < 0) { if ((ret != -EAGAIN) && (ret != -ENOSYS)) { ERROR2(" ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret)); } } } if (state == SND_PCM_STATE_SETUP) { TRACE0("need to call prepare again...\n"); // prepare device ret = snd_pcm_prepare(info->handle); if (ret < 0) { ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret)); } } // in case there is still data in the buffers ret = snd_pcm_start(info->handle); if (ret != 0) { if (ret != -EPIPE) { ERROR2(" NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret)); } } // set to non-blocking mode ret = snd_pcm_nonblock(info->handle, 1); if (ret != 0) { ERROR1(" ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret)); } state = snd_pcm_state(info->handle); #ifdef USE_TRACE printState(state); #endif ret = (state == SND_PCM_STATE_PREPARED) || (state == SND_PCM_STATE_RUNNING) || (state == SND_PCM_STATE_XRUN) || (state == SND_PCM_STATE_SUSPENDED); TRACE1("< DAUDIO_Start %s\n", ret?"success":"error"); return ret?TRUE:FALSE; }
/* Play from alsa_buf as many chunks as possible. Move the remaining data * to the beginning of the buffer. Return the number of bytes written * or -1 on error. */ static int play_buf_chunks () { int written = 0; while (alsa_buf_fill >= chunk_size) { int err; err = snd_pcm_writei (handle, alsa_buf + written, chunk_size / bytes_per_frame); if (err == -EAGAIN) { if (snd_pcm_wait(handle, 500) < 0) logit ("snd_pcm_wait() failed"); } else if (err == -EPIPE) { logit ("underrun!"); if ((err = snd_pcm_prepare(handle)) < 0) { error ("Can't recover after underrun: %s", snd_strerror(err)); /* TODO: reopen the device */ return -1; } } else if (err == -ESTRPIPE) { logit ("Suspend, trying to resume"); while ((err = snd_pcm_resume(handle)) == -EAGAIN) sleep (1); if (err < 0) { logit ("Failed, restarting"); if ((err = snd_pcm_prepare(handle)) < 0) { error ("Failed to restart " "device: %s.", snd_strerror(err)); return -1; } } } else if (err < 0) { error ("Can't play: %s", snd_strerror(err)); return -1; } else { int written_bytes = err * bytes_per_frame; written += written_bytes; alsa_buf_fill -= written_bytes; debug ("Played %d bytes", written_bytes); } } debug ("%d bytes remain in alsa_buf", alsa_buf_fill); memmove (alsa_buf, alsa_buf + written, alsa_buf_fill); return written * bytes_per_frame; }
static void alsaspdifsink_write_frame (AlsaSPDIFSink * sink, guchar * buf) { snd_pcm_sframes_t res; int num_frames = IEC958_FRAME_SIZE / ALSASPDIFSINK_BYTES_PER_FRAME; /* If we couldn't output big endian when we opened the devic, then * we need to swap here */ if (sink->need_swap) { int i; guchar tmp; for (i = 0; i < IEC958_FRAME_SIZE; i += 2) { tmp = buf[i]; buf[i] = buf[i + 1]; buf[i + 1] = tmp; } } res = 0; do { if (res == -EPIPE) { /* Underrun. */ GST_INFO_OBJECT (sink, "buffer underrun"); res = snd_pcm_prepare (sink->pcm); } else if (res == -ESTRPIPE) { /* Suspend. */ while ((res = snd_pcm_resume (sink->pcm)) == -EAGAIN) { GST_DEBUG_OBJECT (sink, "sleeping for suspend"); g_usleep (100000); } if (res < 0) { res = snd_pcm_prepare (sink->pcm); } } if (res >= 0) { res = snd_pcm_writei (sink->pcm, (void *) buf, num_frames); } if (res > 0) { num_frames -= res; } } while (res == -EPIPE || num_frames > 0); sink->frames++; if (res < 0) { GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, ("writei returned error: %s", snd_strerror (res)), GST_ERROR_SYSTEM); return; } }
static int drvHostALSAAudioResume(snd_pcm_t *phPCM) { AssertPtrReturn(phPCM, VERR_INVALID_POINTER); int err = snd_pcm_resume(phPCM); if (err < 0) { LogFunc(("Failed to resume stream %p: %s\n", phPCM, snd_strerror(err))); return VERR_ACCESS_DENIED; /** @todo Find a better rc. */ } return VINF_SUCCESS; }
static int laudio_alsa_xrun_recover(int err) { int ret; if (err != 0) pcm_last_error = err; /* Buffer underrun */ if (err == -EPIPE) { pcm_last_error = 0; ret = snd_pcm_prepare(hdl); if (ret < 0) { DPRINTF(E_WARN, L_LAUDIO, "Couldn't recover from underrun: %s\n", snd_strerror(ret)); return 1; } return 0; } /* Device suspended */ else if (pcm_last_error == -ESTRPIPE) { ret = snd_pcm_resume(hdl); if (ret == -EAGAIN) { pcm_recovery++; return 2; } else if (ret < 0) { pcm_recovery = 0; ret = snd_pcm_prepare(hdl); if (ret < 0) { DPRINTF(E_WARN, L_LAUDIO, "Couldn't recover from suspend: %s\n", snd_strerror(ret)); return 1; } } pcm_recovery = 0; return 0; } return err; }
static int ao_alsa_play(dtaudio_output_t *aout, uint8_t * buf, int size) { alsa_ctx_t *ctx = (alsa_ctx_t *)wrapper->ao_priv; snd_pcm_t *alsa_handle = (snd_pcm_t *) ctx->handle; int bytes_per_sample = wrapper->para.bps * wrapper->para.dst_channels / 8; int num_frames = size / bytes_per_sample; snd_pcm_sframes_t res = 0; uint8_t *data = buf; if (!alsa_handle) { return -1; } if (num_frames == 0) { return 0; } if (ao_alsa_level(aout) >= ctx->buf_threshold) { dt_debug(TAG, "ALSA EXCEED THRESHOLD,size:%d thres:%d \n", ao_alsa_level(aout), ctx->buf_threshold); return 0; } res = snd_pcm_writei(alsa_handle, data, num_frames); if (res == -EINTR) { dt_info(TAG, "ALSA HAS NO SPACE, WRITE AGAIN\n"); return res; } if (res == -ESTRPIPE) { snd_pcm_resume(alsa_handle); return res; } if (res == -EBADFD) { snd_pcm_reset(alsa_handle); return res; } if (res < 0) { snd_pcm_prepare(alsa_handle); dt_info(TAG, "snd pcm write failed prepare!\n"); return -1; //goto rewrite; } if (res < num_frames) { data += res * bytes_per_sample; num_frames -= res; //goto rewrite; } return res * bytes_per_sample; }
static int recover(sox_format_t * ft, snd_pcm_t * pcm, int err) { if (err == -EPIPE) lsx_warn("%s-run", ft->mode == 'r'? "over" : "under"); else if (err != -ESTRPIPE) lsx_warn("%s", snd_strerror(err)); else while ((err = snd_pcm_resume(pcm)) == -EAGAIN) { lsx_report("suspended"); sleep(1); /* Wait until the suspend flag is released */ } if (err < 0 && (err = snd_pcm_prepare(pcm)) < 0) lsx_fail_errno(ft, SOX_EPERM, "%s", snd_strerror(err)); return err; }
static int suspend_recover(void) { int err; while((err = snd_pcm_resume(alsa_pcm)) == -EAGAIN) /* wait until suspend flag is released */ sleep(1); if(err < 0) { printf("alsa_handle_error(): " "snd_pcm_resume() failed.\n"); return snd_pcm_prepare(alsa_pcm); } return err; }
static void suspend(void) { int res; fprintf(stderr, "Suspended. Trying resume. "); fflush(stderr); while ((res = snd_pcm_resume(AHandle)) == -EAGAIN) sleep(1); /* wait until suspend flag is released */ if (res < 0) { fprintf(stderr, "Failed. Restarting stream. "); fflush(stderr); if ((res = snd_pcm_prepare(AHandle)) < 0) { fprintf(stderr, "suspend: prepare error: %s", snd_strerror(res)); } } fprintf(stderr, "Done.\n"); }
BOOL auTransferData(Audio* self, snd_pcm_sframes_t (*transfer)(snd_pcm_t*, void*, snd_pcm_uframes_t)) { int numFramesTransferred = 0, error = 0; int numFramesLeft = self->bufferNumFrames; auSample_t* p = self->sampleBuffer; while((numFramesLeft > 0) && self->threadShouldContinueRunning) { error = numFramesTransferred = transfer(self->device, p, numFramesLeft); if(numFramesTransferred < 0) { //fprintf(stderr, "Audio.c: audio device error while transferring samples: %s, attempting to recover... ", snd_strerror(error)); switch(error) { case -EPIPE: //overflow / underflow snd_pcm_wait(self->device, 100); if((error = snd_pcm_avail(self->device)) < 0) //broken pipe usleep(10000); //wait for more samples to come else numFramesLeft = 0; //overrun, skip remaining samples; error = snd_pcm_prepare(self->device); break; case -ESTRPIPE: while(((error = snd_pcm_resume(self->device)) == -EAGAIN) && self->threadShouldContinueRunning) sleep(1); if(error == -ENOSYS) error = snd_pcm_prepare(self->device); break; } if(error < 0) { //fprintf(stderr, "Aborting\n"); self->threadShouldContinueRunning = NO; break; } else { //fprintf(stderr, "Okay\n"); numFramesTransferred = 0; } } p += numFramesTransferred * self->numChannels; numFramesLeft -= numFramesTransferred; } return (numFramesLeft == 0) ? YES : NO; }
/***************************************************************************** * Demux: Processes the audio frame *****************************************************************************/ static int Demux( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; block_t *p_block = NULL; do { if( p_block ) { es_out_Send( p_demux->out, p_sys->p_es, p_block ); p_block = NULL; } /* Wait for data */ int i_wait = snd_pcm_wait( p_sys->p_alsa_pcm, 10 ); /* See poll() comment in oss.c */ switch( i_wait ) { case 1: { p_block = GrabAudio( p_demux ); if( p_block ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); } /* FIXME: this is a copy paste from below. Shouldn't be needed * twice. */ case -EPIPE: /* xrun */ snd_pcm_prepare( p_sys->p_alsa_pcm ); break; case -ESTRPIPE: { /* suspend */ int i_resume = snd_pcm_resume( p_sys->p_alsa_pcm ); if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm ); break; } /* </FIXME> */ } } while( p_block && p_sys->i_next_demux_date > 0 && p_block->i_pts < p_sys->i_next_demux_date ); if( p_block ) es_out_Send( p_demux->out, p_sys->p_es, p_block ); return 1; }
static int xrun_recovery(snd_pcm_t *handle, int err) { if (err == -EPIPE) { /* under-run */ if ((err = snd_pcm_prepare(handle)) < 0) log_message(LOG_DEFAULT, "Can't recover from underrun, prepare failed: %s", snd_strerror(err)); return 0; } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume(handle)) == -EAGAIN) sleep(1); /* wait until the suspend flag is released */ if (err < 0) { if ((err = snd_pcm_prepare(handle)) < 0) log_message(LOG_DEFAULT, "Can't recover from suspend, prepare failed: %s", snd_strerror(err)); } return 0; } return err; }
static void alsa_write (struct sound_device *sd, const char *buffer, int nbytes) { struct alsa_params *p = (struct alsa_params *) sd->data; /* The the third parameter to snd_pcm_writei is frames, not bytes. */ int fact = snd_pcm_format_size (sd->format, 1) * sd->channels; int nwritten = 0; int err; while (nwritten < nbytes) { snd_pcm_uframes_t frames = (nbytes - nwritten)/fact; if (frames == 0) break; err = snd_pcm_writei (p->handle, buffer + nwritten, frames); if (err < 0) { if (err == -EPIPE) { /* under-run */ err = snd_pcm_prepare (p->handle); if (err < 0) alsa_sound_perror ("Can't recover from underrun, prepare failed", err); } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume (p->handle)) == -EAGAIN) sleep(1); /* wait until the suspend flag is released */ if (err < 0) { err = snd_pcm_prepare (p->handle); if (err < 0) alsa_sound_perror ("Can't recover from suspend, " "prepare failed", err); } } else alsa_sound_perror ("Error writing to sound device", err); } else nwritten += err * fact; } }
int32 ad_read(ad_rec_t * handle, int16 * buf, int32 max) { int32 length, err; if (!handle->recording) { fprintf(stderr, "Recording is stopped, start recording with ad_start_rec\n"); return AD_EOF; } length = snd_pcm_readi(handle->dspH, buf, max); if (length == -EAGAIN) { length = 0; } else if (length == -EPIPE) { fprintf(stderr, "Input overrun, read calls are too rare (non-fatal)\n"); err = snd_pcm_prepare(handle->dspH); if (err < 0) { fprintf(stderr, "Can't recover from underrun: %s\n", snd_strerror(err)); return AD_ERR_GEN; } length = 0; } else if (length == -ESTRPIPE) { fprintf(stderr, "Resuming sound driver (non-fatal)\n"); while ((err = snd_pcm_resume(handle->dspH)) == -EAGAIN) usleep(10000); /* Wait for the driver to wake up */ if (err < 0) { err = snd_pcm_prepare(handle->dspH); if (err < 0) { fprintf(stderr, "Can't recover from underrun: %s\n", snd_strerror(err)); return AD_ERR_GEN; } } length = 0; } else if (length < 0) { fprintf(stderr, "Audio read error: %s\n", snd_strerror(length)); return AD_ERR_GEN; } return length; }
static void alsa_resume(snd_pcm_t *handle){ int err; snd_pcm_status_t *status=NULL; snd_pcm_status_alloca(&status); if ((err=snd_pcm_status(handle,status))!=0){ ms_warning("snd_pcm_status() failed: %s",snd_strerror(err)); return; } if (snd_pcm_status_get_state(status)==SND_PCM_STATE_SUSPENDED){ ms_warning("Maybe suspended, trying resume"); if ((err=snd_pcm_resume(handle))!=0){ if (err!=EWOULDBLOCK) ms_warning("snd_pcm_resume() failed: %s",snd_strerror(err)); } } }
static int xrun_recovery(snd_pcm_t *handle, int err) { // printf( "xrun !!!.... %d\n", err ); if (err == -EPIPE) { /* under-run */ err = snd_pcm_prepare(handle); if (err < 0) printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); return 0; } else if (err == -EAGAIN) { while ((err = snd_pcm_resume(handle)) == -EAGAIN) usleep(100); /* wait until the suspend flag is released */ if (err < 0) { err = snd_pcm_prepare(handle); if (err < 0) printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); } return 0; } return err; }
static int play(void* data, int len, int flags) { int num_frames; snd_pcm_sframes_t res = 0; if (!(flags & AOPLAY_FINAL_CHUNK)) len = len / ao_data.outburst * ao_data.outburst; num_frames = len / bytes_per_sample; //mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: frames=%i, len=%i\n",num_frames,len); if (!alsa_handler) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_DeviceConfigurationError); return 0; } if (num_frames == 0) return 0; do { res = snd_pcm_writei(alsa_handler, data, num_frames); if (res == -EINTR) { /* nothing to do */ res = 0; } else if (res == -ESTRPIPE) { /* suspend */ mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_PcmInSuspendModeTryingResume); while ((res = snd_pcm_resume(alsa_handler)) == -EAGAIN) sleep(1); } if (res < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_WriteError, snd_strerror(res)); mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_TryingToResetSoundcard); if ((res = snd_pcm_prepare(alsa_handler)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(res)); break; } res = 0; } } while (res == 0); return res < 0 ? 0 : res * bytes_per_sample; }
// I/O suspend handler static void suspend(void) { int res; if (!quiet_mode) fprintf(stderr, _("Suspended. Trying resume. ")); fflush(stderr); while ((res = snd_pcm_resume(handle)) == -EAGAIN) sleep(1); // wait until suspend flag is released if (res < 0) { if (!quiet_mode) fprintf(stderr, _("Failed. Restarting stream. ")); fflush(stderr); if ((res = snd_pcm_prepare(handle)) < 0) { error(_("suspend: prepare error: %s"), snd_strerror(res)); exit(EXIT_FAILURE); } } if (!quiet_mode) fprintf(stderr, _("Done.\n")); }
bool AlsaSource::XrunRecovery (int err) { switch (err) { case -EPIPE: // under-run Underflowed (); mutex.Lock (); if (initialized) { err = snd_pcm_prepare (pcm); if (err < 0) { LOG_AUDIO ("AlsaPlayer: Can't recover from underrun, prepare failed: %s.\n", snd_strerror (err)); } } else { LOG_AUDIO ("AlsaPlayer: Can't recover from underrun, pcm has been closed.\n"); } mutex.Unlock (); break; case -ESTRPIPE: mutex.Lock (); if (initialized) { while ((err = snd_pcm_resume (pcm)) == -EAGAIN) { LOG_AUDIO ("XrunRecovery: waiting for resume\n"); sleep (1); // wait until the suspend flag is released } if (err < 0) { err = snd_pcm_prepare (pcm); if (err < 0) { LOG_AUDIO ("AlsaPlayer: Can't recover from suspend, prepare failed: %s.\n", snd_strerror (err)); } } } else { LOG_AUDIO ("AlsaPlayer: Can't recover from suspend, pcm has been closed.\n"); } mutex.Unlock (); break; default: LOG_AUDIO ("AlsaPlayer: Can't recover from underrun: %s\n", snd_strerror (err)); break; } return err >= 0; }
int writei_snd(struct playerHandles *ph, const char *out, const unsigned int size){ int ret; if(ph->pflag->pause){ snd_pcm_drop(ph->sndfd); do{ usleep(100000); // 0.1 seconds } while(ph->pflag->pause); snd_pcm_prepare(ph->sndfd); } if(size==0){ snd_pcm_drain(ph->sndfd); return 0; } ret=snd_pcm_writei(ph->sndfd,out,size); if(ret == -EAGAIN)return 0; if(ret<0){ if(ret == -EPIPE){ ret=snd_pcm_prepare(ph->sndfd); if(ret<0){ snd_pcm_drain(ph->sndfd); snd_pcm_close(ph->sndfd); return -1; } } else if(ret == -ESTRPIPE){ while((ret=snd_pcm_resume(ph->sndfd)) == -EAGAIN) sleep(1); if(ret<0){ ret=snd_pcm_prepare(ph->sndfd); if(ret<0){ snd_pcm_drain(ph->sndfd); snd_pcm_close(ph->sndfd); return -1; } } } } return 0; }
static void ALSA_PlayAudio(_THIS) { int status; int sample_len; signed short *sample_buf; // okay, Veer. this->spec.format may have AUDIO_FORMAT_HW_AC3, // the length of the AC3 frame should be in this->mixbuffer_length if (this->spec.format == AUDIO_FORMAT_HW_AC3) { sample_len = this->mixbuffer_length; } else sample_len = this->spec.samples; sample_buf = (signed short *)mixbuf; while ( sample_len > 0 ) { status = snd_pcm_writei(pcm_handle, sample_buf, sample_len); if ( status < 0 ) { if ( status == -EAGAIN ) { SDL_Delay(1); continue; } if ( status == -ESTRPIPE ) { do { SDL_Delay(1); status = snd_pcm_resume(pcm_handle); } while ( status == -EAGAIN ); } if ( status < 0 ) { status = snd_pcm_prepare(pcm_handle); } if ( status < 0 ) { /* Hmm, not much we can do - abort */ this->enabled = 0; return; } continue; } sample_buf += status * this->spec.channels; sample_len -= status; } }
static size_t pcm_write_raw(alsa_param_t * alsa_param, u_char * data, size_t count) { snd_pcm_sframes_t r; size_t result = 0; /* if (count < chunk_size) { snd_pcm_format_set_silence(hwparams.format, data + count * bits_per_frame / 8, (chunk_size - count) * hwparams.channels); count = chunk_size; } */ while (count > 0) { r = writei_func(alsa_param->handle, data, count); if (r == -EINTR) { r = 0; } if (r == -ESTRPIPE) { while ((r = snd_pcm_resume(alsa_param->handle)) == -EAGAIN) { sleep(1); } } if (r < 0) { //printf("xun in\n"); if ((r = snd_pcm_prepare(alsa_param->handle)) < 0) { return 0; } } if (r > 0) { result += r; count -= r; data += r * alsa_param->bits_per_frame / 8; } } return result; }
static void audio_resume(void) { int err; if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) { mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_PcmInSuspendModeTryingResume); while ((err = snd_pcm_resume(alsa_handler)) == -EAGAIN) sleep(1); } if (alsa_can_pause) { if ((err = snd_pcm_pause(alsa_handler, 0)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmResumeError, snd_strerror(err)); return; } mp_msg(MSGT_AO,MSGL_V,"alsa-resume: resume supported by hardware\n"); } else { if ((err = snd_pcm_prepare(alsa_handler)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); return; } } }
static int xrun_recovery(snd_pcm_t *handle, int err) { if (err == -EPIPE) { /* underrun */ err = snd_pcm_prepare(handle); if (err < 0) { audio_error=snd_strerror(err); return -1; } } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume(handle)) == -EAGAIN) sleep(1); /* wait until suspend flag is gone */ if (err < 0) { err = snd_pcm_prepare(handle); if (err < 0) { audio_error = snd_strerror(err); return -1; } } return 0; } return err; }