Ver código fonte

Merge pull request #53408 from EIRTeam/fix_wasapi_output_latency

Rémi Verschelde 3 anos atrás
pai
commit
0e9d5a41d2

+ 17 - 1
drivers/wasapi/audio_driver_wasapi.cpp

@@ -274,7 +274,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
 		ERR_PRINT("WASAPI: RegisterEndpointNotificationCallback error");
 	}
 
-	bool using_audio_client_3 = !p_capture; // IID_IAudioClient3 is only used for adjustable output latency (not input)
+	using_audio_client_3 = !p_capture; // IID_IAudioClient3 is only used for adjustable output latency (not input)
 	if (using_audio_client_3) {
 		hr = device->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
 		if (hr != S_OK) {
@@ -378,6 +378,13 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
 
 		// Due to WASAPI Shared Mode we have no control of the buffer size
 		buffer_frames = max_frames;
+
+		int64_t latency = 0;
+		audio_output.audio_client->GetStreamLatency(&latency);
+		// WASAPI REFERENCE_TIME units are 100 nanoseconds per unit
+		// https://docs.microsoft.com/en-us/windows/win32/directshow/reference-time
+		// Convert REFTIME to seconds as godot uses for latency
+		real_latency = (float)latency / (float)REFTIMES_PER_SEC;
 	} else {
 		IAudioClient3 *device_audio_client_3 = (IAudioClient3 *)p_device->audio_client;
 
@@ -411,6 +418,11 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
 
 		hr = device_audio_client_3->InitializeSharedAudioStream(0, period_frames, pwfex, nullptr);
 		ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: InitializeSharedAudioStream failed with error 0x" + String::num_uint64(hr, 16) + ".");
+		uint32_t output_latency_in_frames;
+		WAVEFORMATEX *current_pwfex;
+		device_audio_client_3->GetCurrentSharedModeEnginePeriod(&current_pwfex, &output_latency_in_frames);
+		real_latency = (float)output_latency_in_frames / (float)current_pwfex->nSamplesPerSec;
+		CoTaskMemFree(current_pwfex);
 	}
 
 	if (p_capture) {
@@ -518,6 +530,10 @@ int AudioDriverWASAPI::get_mix_rate() const {
 	return mix_rate;
 }
 
+float AudioDriverWASAPI::get_latency() {
+	return real_latency;
+}
+
 AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const {
 	return get_speaker_mode_by_total_channels(channels);
 }

+ 3 - 0
drivers/wasapi/audio_driver_wasapi.h

@@ -73,6 +73,8 @@ class AudioDriverWASAPI : public AudioDriver {
 	int mix_rate = 0;
 	int buffer_frames = 0;
 	int target_latency_ms = 0;
+	float real_latency = 0.0;
+	bool using_audio_client_3 = false;
 
 	bool thread_exited = false;
 	mutable bool exit_thread = false;
@@ -99,6 +101,7 @@ public:
 	virtual Error init();
 	virtual void start();
 	virtual int get_mix_rate() const;
+	virtual float get_latency();
 	virtual SpeakerMode get_speaker_mode() const;
 	virtual Array get_device_list();
 	virtual String get_device();