diff --git a/libobs/audio-monitoring/win32/wasapi-output.c b/libobs/audio-monitoring/win32/wasapi-output.c index 25611409d..1247a1bca 100644 --- a/libobs/audio-monitoring/win32/wasapi-output.c +++ b/libobs/audio-monitoring/win32/wasapi-output.c @@ -41,8 +41,6 @@ struct audio_monitor { uint32_t channels; bool source_has_video; bool ignore; - bool initialized; - bool failure; int64_t lowest_audio_offset; struct circlebuf delay_buffer; @@ -141,13 +139,11 @@ static bool process_audio_delay(struct audio_monitor *monitor, float **data, return false; } -static void audio_monitor_start_device(struct audio_monitor *monitor); - static void on_audio_playback(void *param, obs_source_t *source, const struct audio_data *audio_data, bool muted) { struct audio_monitor *monitor = param; - IAudioRenderClient *render; + IAudioRenderClient *render = monitor->render; uint8_t *resample_data[MAX_AV_PLANES]; float vol = source->user_volume; uint32_t resample_frames; @@ -161,14 +157,6 @@ static void on_audio_playback(void *param, obs_source_t *source, if (os_atomic_load_long(&source->activate_refs) == 0) { goto unlock; } - if (!monitor->failure && !monitor->initialized) { - audio_monitor_start_device(monitor); - } - if (monitor->failure) { - goto unlock; - } - - render = monitor->render; success = audio_resampler_resample( monitor->resampler, resample_data, &resample_frames, &ts_offset, @@ -259,7 +247,10 @@ static enum speaker_layout convert_speaker_layout(DWORD layout, WORD channels) return (enum speaker_layout)channels; } -static void audio_monitor_start_device(struct audio_monitor *monitor) +extern bool devices_match(const char *id1, const char *id2); + +static bool audio_monitor_init(struct audio_monitor *monitor, + obs_source_t *source) { IMMDeviceEnumerator *immde = NULL; WAVEFORMATEX *wfex = NULL; @@ -267,10 +258,26 @@ static void audio_monitor_start_device(struct audio_monitor *monitor) UINT32 frames; HRESULT hr; + pthread_mutex_init_value(&monitor->playback_mutex); + + monitor->source = source; + const char *id = obs->audio.monitoring_device_id; if (!id) { warn("%s: No device ID set", __FUNCTION__); - goto fail; + return false; + } + + if (source->info.output_flags & OBS_SOURCE_DO_NOT_SELF_MONITOR) { + obs_data_t *s = obs_source_get_settings(source); + const char *s_dev_id = obs_data_get_string(s, "device_id"); + bool match = devices_match(s_dev_id, id); + obs_data_release(s); + + if (match) { + monitor->ignore = true; + return true; + } } /* ------------------------------------------ * @@ -281,7 +288,7 @@ static void audio_monitor_start_device(struct audio_monitor *monitor) if (FAILED(hr)) { warn("%s: Failed to create IMMDeviceEnumerator: %08lX", __FUNCTION__, hr); - goto fail; + return false; } if (strcmp(id, "default") == 0) { @@ -367,6 +374,11 @@ static void audio_monitor_start_device(struct audio_monitor *monitor) goto fail; } + if (pthread_mutex_init(&monitor->playback_mutex, NULL) != 0) { + warn("%s: Failed to initialize mutex", __FUNCTION__); + goto fail; + } + hr = monitor->client->lpVtbl->Start(monitor->client); if (FAILED(hr)) { warn("%s: Failed to start audio: %08lX", __FUNCTION__, hr); @@ -374,49 +386,12 @@ static void audio_monitor_start_device(struct audio_monitor *monitor) } success = true; - monitor->initialized = true; fail: - if (!success) - monitor->failure = true; - safe_release(immde); if (wfex) CoTaskMemFree(wfex); -} - -extern bool devices_match(const char *id1, const char *id2); - -static bool audio_monitor_init(struct audio_monitor *monitor, - obs_source_t *source) -{ - pthread_mutex_init_value(&monitor->playback_mutex); - - monitor->source = source; - - const char *id = obs->audio.monitoring_device_id; - if (!id) { - warn("%s: No device ID set", __FUNCTION__); - return false; - } - - if (pthread_mutex_init(&monitor->playback_mutex, NULL) != 0) { - warn("%s: Failed to initialize mutex", __FUNCTION__); - return false; - } - - if (source->info.output_flags & OBS_SOURCE_DO_NOT_SELF_MONITOR) { - obs_data_t *s = obs_source_get_settings(source); - const char *s_dev_id = obs_data_get_string(s, "device_id"); - bool match = devices_match(s_dev_id, id); - obs_data_release(s); - - if (match) { - monitor->ignore = true; - } - } - - return true; + return success; } static void audio_monitor_init_final(struct audio_monitor *monitor)