ソースを参照

UI: Display grayscale volume meter if muted

Currently, the volume meters don't show volume levels when
muted. This shows the levels and makes it grayscale when
the source is muted.
Clayton Groeneveld 4 年 前
コミット
5878856ce4
3 ファイル変更51 行追加21 行削除
  1. 44 20
      UI/volume-control.cpp
  2. 5 0
      UI/volume-control.hpp
  3. 2 1
      libobs/obs-audio-controls.c

+ 44 - 20
UI/volume-control.cpp

@@ -60,6 +60,8 @@ void VolControl::VolumeMuted(bool muted)
 {
 	if (mute->isChecked() != muted)
 		mute->setChecked(muted);
+
+	volMeter->muted = muted;
 }
 
 void VolControl::SetMuted(bool checked)
@@ -280,6 +282,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
 
 	bool muted = obs_source_muted(source);
 	mute->setChecked(muted);
+	volMeter->muted = muted;
 	mute->setAccessibleName(QTStr("VolControl.Mute").arg(sourceName));
 	obs_fader_add_callback(obs_fader, OBSVolumeChanged, this);
 	obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this);
@@ -852,6 +855,15 @@ void VolumeMeter::ClipEnding()
 	clipping = false;
 }
 
+QColor VolumeMeter::ConvertToGrayscale(const QColor &color) const
+{
+	if (!muted)
+		return color;
+
+	int gray = qGray(color.rgb());
+	return QColor(gray, gray, gray);
+}
+
 void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
 			      int height, float magnitude, float peak,
 			      float peakHold)
@@ -876,44 +888,56 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
 		peakPosition = maximumPosition;
 	}
 
+	QColor backgroundNominalColor_ =
+		ConvertToGrayscale(backgroundNominalColor);
+	QColor backgroundWarningColor_ =
+		ConvertToGrayscale(backgroundWarningColor);
+	QColor backgroundErrorColor_ = ConvertToGrayscale(backgroundErrorColor);
+	QColor foregroundNominalColor_ =
+		ConvertToGrayscale(foregroundNominalColor);
+	QColor foregroundWarningColor_ =
+		ConvertToGrayscale(foregroundWarningColor);
+	QColor foregroundErrorColor_ = ConvertToGrayscale(foregroundErrorColor);
+	QColor magnitudeColor_ = ConvertToGrayscale(magnitudeColor);
+
 	if (peakPosition < minimumPosition) {
 		painter.fillRect(minimumPosition, y, nominalLength, height,
-				 backgroundNominalColor);
+				 backgroundNominalColor_);
 		painter.fillRect(warningPosition, y, warningLength, height,
-				 backgroundWarningColor);
+				 backgroundWarningColor_);
 		painter.fillRect(errorPosition, y, errorLength, height,
-				 backgroundErrorColor);
+				 backgroundErrorColor_);
 	} else if (peakPosition < warningPosition) {
 		painter.fillRect(minimumPosition, y,
 				 peakPosition - minimumPosition, height,
-				 foregroundNominalColor);
+				 foregroundNominalColor_);
 		painter.fillRect(peakPosition, y,
 				 warningPosition - peakPosition, height,
-				 backgroundNominalColor);
+				 backgroundNominalColor_);
 		painter.fillRect(warningPosition, y, warningLength, height,
-				 backgroundWarningColor);
+				 backgroundWarningColor_);
 		painter.fillRect(errorPosition, y, errorLength, height,
-				 backgroundErrorColor);
+				 backgroundErrorColor_);
 	} else if (peakPosition < errorPosition) {
 		painter.fillRect(minimumPosition, y, nominalLength, height,
-				 foregroundNominalColor);
+				 foregroundNominalColor_);
 		painter.fillRect(warningPosition, y,
 				 peakPosition - warningPosition, height,
-				 foregroundWarningColor);
+				 foregroundWarningColor_);
 		painter.fillRect(peakPosition, y, errorPosition - peakPosition,
-				 height, backgroundWarningColor);
+				 height, backgroundWarningColor_);
 		painter.fillRect(errorPosition, y, errorLength, height,
-				 backgroundErrorColor);
+				 backgroundErrorColor_);
 	} else if (peakPosition < maximumPosition) {
 		painter.fillRect(minimumPosition, y, nominalLength, height,
-				 foregroundNominalColor);
+				 foregroundNominalColor_);
 		painter.fillRect(warningPosition, y, warningLength, height,
-				 foregroundWarningColor);
+				 foregroundWarningColor_);
 		painter.fillRect(errorPosition, y, peakPosition - errorPosition,
-				 height, foregroundErrorColor);
+				 height, foregroundErrorColor_);
 		painter.fillRect(peakPosition, y,
 				 maximumPosition - peakPosition, height,
-				 backgroundErrorColor);
+				 backgroundErrorColor_);
 	} else if (int(magnitude) != 0) {
 		if (!clipping) {
 			QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
@@ -923,24 +947,24 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
 
 		int end = errorLength + warningLength + nominalLength;
 		painter.fillRect(minimumPosition, y, end, height,
-				 QBrush(foregroundErrorColor));
+				 QBrush(foregroundErrorColor_));
 	}
 
 	if (peakHoldPosition - 3 < minimumPosition)
 		; // Peak-hold below minimum, no drawing.
 	else if (peakHoldPosition < warningPosition)
 		painter.fillRect(peakHoldPosition - 3, y, 3, height,
-				 foregroundNominalColor);
+				 foregroundNominalColor_);
 	else if (peakHoldPosition < errorPosition)
 		painter.fillRect(peakHoldPosition - 3, y, 3, height,
-				 foregroundWarningColor);
+				 foregroundWarningColor_);
 	else
 		painter.fillRect(peakHoldPosition - 3, y, 3, height,
-				 foregroundErrorColor);
+				 foregroundErrorColor_);
 
 	if (magnitudePosition - 3 >= minimumPosition)
 		painter.fillRect(magnitudePosition - 3, y, 3, height,
-				 magnitudeColor);
+				 magnitudeColor_);
 }
 
 void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,

+ 5 - 0
UI/volume-control.hpp

@@ -62,6 +62,8 @@ class VolumeMeter : public QWidget {
 	Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration
 			   WRITE setInputPeakHoldDuration DESIGNABLE true)
 
+	friend class VolControl;
+
 private slots:
 	void ClipEnding();
 
@@ -88,6 +90,8 @@ private:
 			 float magnitude, float peak, float peakHold);
 	void paintVTicks(QPainter &painter, int x, int y, int height);
 
+	QColor ConvertToGrayscale(const QColor &color) const;
+
 	QMutex dataMutex;
 
 	uint64_t currentLastUpdateTime = 0;
@@ -129,6 +133,7 @@ private:
 	int channels = 0;
 	bool clipping = false;
 	bool vertical;
+	bool muted = false;
 
 public:
 	explicit VolumeMeter(QWidget *parent = nullptr,

+ 2 - 1
libobs/obs-audio-controls.c

@@ -535,7 +535,7 @@ static void volmeter_source_data_received(void *vptr, obs_source_t *source,
 
 	// Adjust magnitude/peak based on the volume level set by the user.
 	// And convert to dB.
-	mul = muted ? 0.0f : db_to_mul(volmeter->cur_db);
+	mul = db_to_mul(volmeter->cur_db);
 	for (int channel_nr = 0; channel_nr < MAX_AUDIO_CHANNELS;
 	     channel_nr++) {
 		magnitude[channel_nr] =
@@ -552,6 +552,7 @@ static void volmeter_source_data_received(void *vptr, obs_source_t *source,
 	signal_levels_updated(volmeter, magnitude, peak, input_peak);
 
 	UNUSED_PARAMETER(source);
+	UNUSED_PARAMETER(muted);
 }
 
 obs_fader_t *obs_fader_create(enum obs_fader_type type)