mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 19:05:37 +00:00
Always use WASAPI's callback mode (#264)
* Hardcodes wasapi GUIDs when compiling as C * Uses the user requested buffer size on wasapi Windows appears to automatically adjust the timer period when you use a small buffer, meaning that using a fraction of a large buffer is unreliable unless you call timeBeginPeriod. Seems simpler to just request the desired size directly. I'll do some further investigations into this, if it seems like the right change to make I'll update the docs as well if needed. * Switches to event driven callbacks on wasapi * Removes some commented out code, moves class variable to local
This commit is contained in:
parent
8ab3606912
commit
a24148e15f
46
src/wasapi.c
46
src/wasapi.c
|
@ -1281,9 +1281,10 @@ static int outstream_do_open(struct SoundIoPrivate *si, struct SoundIoOutStreamP
|
|||
CoTaskMemFree(mix_format);
|
||||
mix_format = NULL;
|
||||
flags = osw->need_resample ? AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY : 0;
|
||||
flags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
|
||||
share_mode = AUDCLNT_SHAREMODE_SHARED;
|
||||
periodicity = 0;
|
||||
buffer_duration = to_reference_time(4.0);
|
||||
buffer_duration = to_reference_time(outstream->software_latency);
|
||||
}
|
||||
to_wave_format_layout(&outstream->layout, &wave_format);
|
||||
to_wave_format_format(outstream->format, &wave_format);
|
||||
|
@ -1313,6 +1314,7 @@ static int outstream_do_open(struct SoundIoPrivate *si, struct SoundIoOutStreamP
|
|||
CoTaskMemFree(mix_format);
|
||||
mix_format = NULL;
|
||||
flags = osw->need_resample ? AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY : 0;
|
||||
flags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
|
||||
to_wave_format_layout(&outstream->layout, &wave_format);
|
||||
to_wave_format_format(outstream->format, &wave_format);
|
||||
complete_wave_format_data(&wave_format);
|
||||
|
@ -1353,11 +1355,9 @@ static int outstream_do_open(struct SoundIoPrivate *si, struct SoundIoOutStreamP
|
|||
}
|
||||
outstream->software_latency = osw->buffer_frame_count / (double)outstream->sample_rate;
|
||||
|
||||
if (osw->is_raw) {
|
||||
if (FAILED(hr = IAudioClient_SetEventHandle(osw->audio_client, osw->h_event))) {
|
||||
return SoundIoErrorOpeningDevice;
|
||||
}
|
||||
}
|
||||
|
||||
if (outstream->name) {
|
||||
if (FAILED(hr = IAudioClient_GetService(osw->audio_client, IID_IAUDIOSESSIONCONTROL,
|
||||
|
@ -1408,13 +1408,13 @@ static void outstream_shared_run(struct SoundIoOutStreamPrivate *os) {
|
|||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
osw->writable_frame_count = osw->buffer_frame_count - frames_used;
|
||||
if (osw->writable_frame_count <= 0) {
|
||||
int writable_frame_count = osw->buffer_frame_count - frames_used;
|
||||
if (writable_frame_count <= 0) {
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
int frame_count_min = soundio_int_max(0, (int)osw->min_padding_frames - (int)frames_used);
|
||||
outstream->write_callback(outstream, frame_count_min, osw->writable_frame_count);
|
||||
outstream->write_callback(outstream, frame_count_min, writable_frame_count);
|
||||
|
||||
if (FAILED(hr = IAudioClient_Start(osw->audio_client))) {
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
|
@ -1422,20 +1422,8 @@ static void outstream_shared_run(struct SoundIoOutStreamPrivate *os) {
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
if (FAILED(hr = IAudioClient_GetCurrentPadding(osw->audio_client, &frames_used))) {
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
if (!SOUNDIO_ATOMIC_FLAG_TEST_AND_SET(osw->thread_exit_flag))
|
||||
return;
|
||||
}
|
||||
osw->writable_frame_count = osw->buffer_frame_count - frames_used;
|
||||
double time_until_underrun = frames_used / (double)outstream->sample_rate;
|
||||
double wait_time = time_until_underrun / 2.0;
|
||||
soundio_os_mutex_lock(osw->mutex);
|
||||
soundio_os_cond_timed_wait(osw->cond, osw->mutex, wait_time);
|
||||
if (!SOUNDIO_ATOMIC_FLAG_TEST_AND_SET(osw->thread_exit_flag)) {
|
||||
soundio_os_mutex_unlock(osw->mutex);
|
||||
return;
|
||||
}
|
||||
soundio_os_mutex_unlock(osw->mutex);
|
||||
bool reset_buffer = false;
|
||||
if (!SOUNDIO_ATOMIC_FLAG_TEST_AND_SET(osw->clear_buffer_flag)) {
|
||||
if (!osw->is_paused) {
|
||||
|
@ -1473,12 +1461,12 @@ static void outstream_shared_run(struct SoundIoOutStreamPrivate *os) {
|
|||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
osw->writable_frame_count = osw->buffer_frame_count - frames_used;
|
||||
if (osw->writable_frame_count > 0) {
|
||||
int writable_frame_count = osw->buffer_frame_count - frames_used;
|
||||
if (writable_frame_count > 0) {
|
||||
if (frames_used == 0 && !reset_buffer)
|
||||
outstream->underflow_callback(outstream);
|
||||
int frame_count_min = soundio_int_max(0, (int)osw->min_padding_frames - (int)frames_used);
|
||||
outstream->write_callback(outstream, frame_count_min, osw->writable_frame_count);
|
||||
outstream->write_callback(outstream, frame_count_min, writable_frame_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1598,13 +1586,11 @@ static int outstream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStr
|
|||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
if (osw->is_raw) {
|
||||
osw->h_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (!osw->h_event) {
|
||||
outstream_destroy_wasapi(si, os);
|
||||
return SoundIoErrorOpeningDevice;
|
||||
}
|
||||
}
|
||||
|
||||
SOUNDIO_ATOMIC_FLAG_TEST_AND_SET(osw->thread_exit_flag);
|
||||
int err;
|
||||
|
@ -1633,13 +1619,7 @@ static int outstream_pause_wasapi(struct SoundIoPrivate *si, struct SoundIoOutSt
|
|||
|
||||
SOUNDIO_ATOMIC_STORE(osw->desired_pause_state, pause);
|
||||
SOUNDIO_ATOMIC_FLAG_CLEAR(osw->pause_resume_flag);
|
||||
if (osw->h_event) {
|
||||
SetEvent(osw->h_event);
|
||||
} else {
|
||||
soundio_os_mutex_lock(osw->mutex);
|
||||
soundio_os_cond_signal(osw->cond, osw->mutex);
|
||||
soundio_os_mutex_unlock(osw->mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1694,13 +1674,11 @@ static int outstream_end_write_wasapi(struct SoundIoPrivate *si, struct SoundIoO
|
|||
static int outstream_clear_buffer_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
||||
struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi;
|
||||
|
||||
if (osw->h_event) {
|
||||
if (osw->is_raw) {
|
||||
return SoundIoErrorIncompatibleDevice;
|
||||
} else {
|
||||
SOUNDIO_ATOMIC_FLAG_CLEAR(osw->clear_buffer_flag);
|
||||
soundio_os_mutex_lock(osw->mutex);
|
||||
soundio_os_cond_signal(osw->cond, osw->mutex);
|
||||
soundio_os_mutex_unlock(osw->mutex);
|
||||
SetEvent(osw->h_event);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -73,7 +73,6 @@ struct SoundIoOutStreamWasapi {
|
|||
struct SoundIoOsCond *start_cond;
|
||||
struct SoundIoAtomicFlag thread_exit_flag;
|
||||
bool is_raw;
|
||||
int writable_frame_count;
|
||||
UINT32 buffer_frame_count;
|
||||
int write_frame_count;
|
||||
HANDLE h_event;
|
||||
|
|
Loading…
Reference in a new issue