/** * @brief Handle audio output */ void OpenAL2::doOutput() { alcMakeContextCurrent(alOutContext); ALuint bufids[PROXY_BUFFER_COUNT]; ALint processed = 0, queued = 0; alGetSourcei(alProxySource, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(alProxySource, AL_BUFFERS_QUEUED, &queued); if (processed > 0) { // unqueue all processed buffers alSourceUnqueueBuffers(alProxySource, processed, bufids); // delete all but the first buffer, reuse first for new data alDeleteBuffers(processed - 1, bufids + 1); } else if (queued < PROXY_BUFFER_COUNT) { // create new buffer until the maximum is reached alGenBuffers(1, bufids); } else { alcMakeContextCurrent(alProxyContext); return; } ALdouble latency[2] = {0}; alGetSourcedvSOFT(alProxySource, AL_SEC_OFFSET_LATENCY_SOFT, latency); checkAlError(); ALshort outBuf[AUDIO_FRAME_SAMPLE_COUNT] = {0}; alcMakeContextCurrent(alProxyContext); alcRenderSamplesSOFT(alProxyDev, outBuf, AUDIO_FRAME_SAMPLE_COUNT); checkAlcError(alProxyDev); alcMakeContextCurrent(alOutContext); alBufferData(bufids[0], AL_FORMAT_MONO16, outBuf, AUDIO_FRAME_SAMPLE_COUNT * 2, AUDIO_SAMPLE_RATE); alSourceQueueBuffers(alProxySource, 1, bufids); // initialize echo canceler if supported if (!filterer) { filterer = new_filter_audio(AUDIO_SAMPLE_RATE); int16_t filterLatency = latency[1] * 1000 * 2 + AUDIO_FRAME_DURATION; qDebug() << "Setting filter delay to: " << filterLatency << "ms"; set_echo_delay_ms(filterer, filterLatency); enable_disable_filters(filterer, 1, 1, 1, 0); } // do echo cancel pass_audio_output(filterer, outBuf, AUDIO_FRAME_SAMPLE_COUNT); ALint state; alGetSourcei(alProxySource, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { qDebug() << "Proxy source underflow detected"; alSourcePlay(alProxySource); } alcMakeContextCurrent(alProxyContext); }
JNIEXPORT void JNICALL Java_org_lwjgl_openal_SOFTSourceLatency_nalGetSourcedvSOFT(JNIEnv *__env, jclass clazz, jint source, jint param, jlong valuesAddress, jlong __functionAddress) { ALdouble *values = (ALdouble *)(intptr_t)valuesAddress; alGetSourcedvSOFTPROC alGetSourcedvSOFT = (alGetSourcedvSOFTPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) alGetSourcedvSOFT(source, param, values); }