static void alsa_stop_capture(ALCdevice *Device) { alsa_data *data = (alsa_data*)Device->ExtraData; ALCuint avail; int err; /* OpenAL requires access to unread audio after stopping, but ALSA's * snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's * available now so it'll be available later after the drop. */ avail = alsa_available_samples(Device); if(!data->ring && avail > 0) { /* The ring buffer implicitly captures when checking availability. * Direct access needs to explicitly capture it into temp storage. */ ALsizei size; void *ptr; size = snd_pcm_frames_to_bytes(data->pcmHandle, avail); ptr = realloc(data->buffer, size); if(ptr) { data->buffer = ptr; alsa_capture_samples(Device, data->buffer, avail); data->size = size; } } err = snd_pcm_drop(data->pcmHandle); if(err < 0) ERR("drop failed: %s\n", snd_strerror(err)); data->doCapture = AL_FALSE; }
static void alsa_capture_samples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples) { alsa_data *data = (alsa_data*)Device->ExtraData; if(Samples <= alsa_available_samples(Device)) ReadRingBuffer(data->ring, Buffer, Samples); else alcSetError(Device, ALC_INVALID_VALUE); }