From 058ff5c3dccc92241ecb02ce3a4dc70fe6d599cd Mon Sep 17 00:00:00 2001
From: Zachary Lund <zachary.lund@streamlabs.com>
Date: Fri, 19 Oct 2018 14:38:55 -0700
Subject: [PATCH] Simplify volmeter logic by removing data swap

This should potentially fix a race condition that zeroes out current
data values as well if you query to quickly.
---
 obs-studio-client/source/volmeter.cpp     |  1 -
 obs-studio-server/source/osn-volmeter.cpp | 42 ++++++++---------------
 obs-studio-server/source/osn-volmeter.hpp |  5 ++-
 3 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/obs-studio-client/source/volmeter.cpp b/obs-studio-client/source/volmeter.cpp
index 4020c20c2..c31de003b 100644
--- a/obs-studio-client/source/volmeter.cpp
+++ b/obs-studio-client/source/volmeter.cpp
@@ -178,7 +178,6 @@ void osn::VolMeter::worker()
 		totalSleepMS = m_sleep_interval - dur.count();
 		std::this_thread::sleep_for(std::chrono::milliseconds(totalSleepMS));
 	}
-	return;
 }
 
 void osn::VolMeter::set_keepalive(v8::Local<v8::Object> obj)
diff --git a/obs-studio-server/source/osn-volmeter.cpp b/obs-studio-server/source/osn-volmeter.cpp
index 947da9336..4e543766f 100644
--- a/obs-studio-server/source/osn-volmeter.cpp
+++ b/obs-studio-server/source/osn-volmeter.cpp
@@ -293,25 +293,20 @@ void osn::VolMeter::Query(
 		return;
 	}
 
-	std::unique_lock<std::mutex> ulock(meter->current_data_mtx);
 	rval.push_back(ipc::value((uint64_t)ErrorCode::Ok));
-	if (meter->current_data) {
-		rval.push_back(ipc::value(meter->current_data->ch));
-		for (size_t ch = 0; ch < meter->current_data->ch; ch++) {
-			rval.push_back(ipc::value(meter->current_data->magnitude[ch]));
-			rval.push_back(ipc::value(meter->current_data->peak[ch]));
-			rval.push_back(ipc::value(meter->current_data->input_peak[ch]));
-		}
-	} else {
-		rval.push_back(ipc::value(0));
-	}
 
-	if (meter->current_data) {
-		std::unique_lock<std::mutex> flock(meter->free_data_mtx);
-		meter->free_data    = meter->current_data;
-		meter->current_data = nullptr;
+	std::unique_lock<std::mutex> ulock(meter->current_data_mtx);
+
+	rval.push_back(ipc::value(meter->current_data.ch));
+
+	for (size_t ch = 0; ch < meter->current_data.ch; ch++) {
+		rval.push_back(ipc::value(meter->current_data.magnitude[ch]));
+		rval.push_back(ipc::value(meter->current_data.peak[ch]));
+		rval.push_back(ipc::value(meter->current_data.input_peak[ch]));
 	}
 
+	ulock.unlock();
+
 	AUTO_DEBUG;
 }
 
@@ -329,22 +324,13 @@ void osn::VolMeter::OBSCallback(
 #define MAKE_FLOAT_SANE(db) (std::isfinite(db) ? db : (db > 0 ? 0.0f : -65535.0f))
 #define PREVIOUS_FRAME_WEIGHT
 
-	// This is a simple swap operation.
 	std::unique_lock<std::mutex> ulock(meter->current_data_mtx);
-	if (!meter->current_data) {
-		std::unique_lock<std::mutex> ulock(meter->free_data_mtx);
-		if (!meter->free_data) {
-			meter->free_data = std::make_shared<AudioData>();
-		}
-		meter->current_data = meter->free_data;
-		meter->free_data    = nullptr;
-	}
 
-	meter->current_data->ch = obs_volmeter_get_nr_channels(meter->self);
+	meter->current_data.ch = obs_volmeter_get_nr_channels(meter->self);
 	for (size_t ch = 0; ch < MAX_AUDIO_CHANNELS; ch++) {
-		meter->current_data->magnitude[ch]  = MAKE_FLOAT_SANE(magnitude[ch]);
-		meter->current_data->peak[ch]       = MAKE_FLOAT_SANE(peak[ch]);
-		meter->current_data->input_peak[ch] = MAKE_FLOAT_SANE(input_peak[ch]);
+		meter->current_data.magnitude[ch]  = MAKE_FLOAT_SANE(magnitude[ch]);
+		meter->current_data.peak[ch]       = MAKE_FLOAT_SANE(peak[ch]);
+		meter->current_data.input_peak[ch] = MAKE_FLOAT_SANE(input_peak[ch]);
 	}
 
 #undef MAKE_FLOAT_SANE
diff --git a/obs-studio-server/source/osn-volmeter.hpp b/obs-studio-server/source/osn-volmeter.hpp
index 30e42c465..9b91b426e 100644
--- a/obs-studio-server/source/osn-volmeter.hpp
+++ b/obs-studio-server/source/osn-volmeter.hpp
@@ -56,10 +56,9 @@ namespace osn
 			float   input_peak[MAX_AUDIO_CHANNELS] = {0};
 			int32_t ch                             = 0;
 		};
-		std::shared_ptr<AudioData> current_data;
+
+		AudioData current_data;
 		std::mutex                 current_data_mtx;
-		std::shared_ptr<AudioData> free_data;
-		std::mutex                 free_data_mtx;
 
 		public:
 		VolMeter(obs_fader_type type);