static ALuint ALSANoMMapProc(ALvoid *ptr) { ALCdevice *pDevice = (ALCdevice*)ptr; alsa_data *data = (alsa_data*)pDevice->ExtraData; snd_pcm_sframes_t avail; char *WritePtr; SetRTPriority(); while(!data->killNow) { int state = verify_state(data->pcmHandle); if(state < 0) { AL_PRINT("Invalid state detected: %s\n", psnd_strerror(state)); aluHandleDisconnect(pDevice); break; } WritePtr = data->buffer; avail = data->size / psnd_pcm_frames_to_bytes(data->pcmHandle, 1); aluMixData(pDevice, WritePtr, avail); while(avail > 0) { int ret = psnd_pcm_writei(data->pcmHandle, WritePtr, avail); switch (ret) { case -EAGAIN: continue; case -ESTRPIPE: case -EPIPE: case -EINTR: ret = psnd_pcm_recover(data->pcmHandle, ret, 1); if(ret >= 0) psnd_pcm_prepare(data->pcmHandle); break; default: if (ret >= 0) { WritePtr += psnd_pcm_frames_to_bytes(data->pcmHandle, ret); avail -= ret; } break; } if (ret < 0) { ret = psnd_pcm_prepare(data->pcmHandle); if(ret < 0) break; } } } return 0; }
static int xrun_recovery(snd_pcm_t *handle, int err) { if(err == -EINTR || err == -EPIPE || err == -ESTRPIPE) { err = psnd_pcm_recover(handle, err, 1); if(err >= 0) err = psnd_pcm_prepare(handle); if(err < 0) AL_PRINT("recover failed: %s\n", psnd_strerror(err)); } return err; }
static unsigned int ALSA_RW_GetDMAPos (soundcardinfo_t *sc) { int frames; frames = psnd_pcm_avail_update(sc->handle); if (frames < 0) { psnd_pcm_start (sc->handle); psnd_pcm_recover(sc->handle, frames, true); frames = psnd_pcm_avail_update(sc->handle); } if (frames >= 0) { sc->sn.samplepos = (sc->snd_sent + frames) * sc->sn.numchannels; } return sc->sn.samplepos; }
static ALCuint alsa_available_samples(ALCdevice *Device) { alsa_data *data = (alsa_data*)Device->ExtraData; snd_pcm_sframes_t avail; avail = (Device->Connected ? psnd_pcm_avail_update(data->pcmHandle) : 0); if(avail < 0) { AL_PRINT("avail update failed: %s\n", psnd_strerror(avail)); if((avail=psnd_pcm_recover(data->pcmHandle, avail, 1)) >= 0 && (avail=psnd_pcm_prepare(data->pcmHandle)) >= 0) { if(data->doCapture) avail = psnd_pcm_start(data->pcmHandle); if(avail >= 0) avail = psnd_pcm_avail_update(data->pcmHandle); } if(avail < 0) { AL_PRINT("restore error: %s\n", psnd_strerror(avail)); aluHandleDisconnect(Device); } } while(avail > 0) { snd_pcm_sframes_t amt; amt = psnd_pcm_bytes_to_frames(data->pcmHandle, data->size); if(avail < amt) amt = avail; amt = psnd_pcm_readi(data->pcmHandle, data->buffer, amt); if(amt < 0) { AL_PRINT("read error: %s\n", psnd_strerror(amt)); if(amt == -EAGAIN) continue; if((amt=psnd_pcm_recover(data->pcmHandle, amt, 1)) >= 0 && (amt=psnd_pcm_prepare(data->pcmHandle)) >= 0) { if(data->doCapture) amt = psnd_pcm_start(data->pcmHandle); if(amt >= 0) amt = psnd_pcm_avail_update(data->pcmHandle); } if(amt < 0) { AL_PRINT("restore error: %s\n", psnd_strerror(amt)); aluHandleDisconnect(Device); break; } avail = amt; continue; } WriteRingBuffer(data->ring, data->buffer, amt); avail -= amt; } return RingBufferSize(data->ring); }