volume-control.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #pragma once
  2. #include <obs.hpp>
  3. #include <QWidget>
  4. #include <QPaintEvent>
  5. #include <QSharedPointer>
  6. #include <QTimer>
  7. #include <QMutex>
  8. #include <QList>
  9. class QPushButton;
  10. class VolumeMeterTimer;
  11. class VolumeMeter : public QWidget
  12. {
  13. Q_OBJECT
  14. Q_PROPERTY(QColor backgroundNominalColor
  15. READ getBackgroundNominalColor
  16. WRITE setBackgroundNominalColor DESIGNABLE true)
  17. Q_PROPERTY(QColor backgroundWarningColor
  18. READ getBackgroundWarningColor
  19. WRITE setBackgroundWarningColor DESIGNABLE true)
  20. Q_PROPERTY(QColor backgroundErrorColor
  21. READ getBackgroundErrorColor
  22. WRITE setBackgroundErrorColor DESIGNABLE true)
  23. Q_PROPERTY(QColor foregroundNominalColor
  24. READ getForegroundNominalColor
  25. WRITE setForegroundNominalColor DESIGNABLE true)
  26. Q_PROPERTY(QColor foregroundWarningColor
  27. READ getForegroundWarningColor
  28. WRITE setForegroundWarningColor DESIGNABLE true)
  29. Q_PROPERTY(QColor foregroundErrorColor
  30. READ getForegroundErrorColor
  31. WRITE setForegroundErrorColor DESIGNABLE true)
  32. Q_PROPERTY(QColor clipColor
  33. READ getClipColor
  34. WRITE setClipColor DESIGNABLE true)
  35. Q_PROPERTY(QColor magnitudeColor
  36. READ getMagnitudeColor
  37. WRITE setMagnitudeColor DESIGNABLE true)
  38. Q_PROPERTY(QColor majorTickColor
  39. READ getMajorTickColor
  40. WRITE setMajorTickColor DESIGNABLE true)
  41. Q_PROPERTY(QColor minorTickColor
  42. READ getMinorTickColor
  43. WRITE setMinorTickColor DESIGNABLE true)
  44. // Levels are denoted in dBFS.
  45. Q_PROPERTY(qreal minimumLevel
  46. READ getMinimumLevel
  47. WRITE setMinimumLevel DESIGNABLE true)
  48. Q_PROPERTY(qreal warningLevel
  49. READ getWarningLevel
  50. WRITE setWarningLevel DESIGNABLE true)
  51. Q_PROPERTY(qreal errorLevel
  52. READ getErrorLevel
  53. WRITE setErrorLevel DESIGNABLE true)
  54. Q_PROPERTY(qreal clipLevel
  55. READ getClipLevel
  56. WRITE setClipLevel DESIGNABLE true)
  57. Q_PROPERTY(qreal minimumInputLevel
  58. READ getMinimumInputLevel
  59. WRITE setMinimumInputLevel DESIGNABLE true)
  60. // Rates are denoted in dB/second.
  61. Q_PROPERTY(qreal peakDecayRate
  62. READ getPeakDecayRate
  63. WRITE setPeakDecayRate DESIGNABLE true)
  64. // Time in seconds for the VU meter to integrate over.
  65. Q_PROPERTY(qreal magnitudeIntegrationTime
  66. READ getMagnitudeIntegrationTime
  67. WRITE setMagnitudeIntegrationTime DESIGNABLE true)
  68. // Duration is denoted in seconds.
  69. Q_PROPERTY(qreal peakHoldDuration
  70. READ getPeakHoldDuration
  71. WRITE setPeakHoldDuration DESIGNABLE true)
  72. Q_PROPERTY(qreal inputPeakHoldDuration
  73. READ getInputPeakHoldDuration
  74. WRITE setInputPeakHoldDuration DESIGNABLE true)
  75. private slots:
  76. void ClipEnding();
  77. private:
  78. obs_volmeter_t *obs_volmeter;
  79. static QWeakPointer<VolumeMeterTimer> updateTimer;
  80. QSharedPointer<VolumeMeterTimer> updateTimerRef;
  81. inline void resetLevels();
  82. inline void handleChannelCofigurationChange();
  83. inline bool detectIdle(uint64_t ts);
  84. inline void calculateBallistics(uint64_t ts,
  85. qreal timeSinceLastRedraw=0.0);
  86. inline void calculateBallisticsForChannel(int channelNr,
  87. uint64_t ts, qreal timeSinceLastRedraw);
  88. void paintInputMeter(QPainter &painter, int x, int y, int width,
  89. int height, float peakHold);
  90. void paintHMeter(QPainter &painter, int x, int y, int width, int height,
  91. float magnitude, float peak, float peakHold);
  92. void paintHTicks(QPainter &painter, int x, int y, int width,
  93. int height);
  94. void paintVMeter(QPainter &painter, int x, int y, int width, int height,
  95. float magnitude, float peak, float peakHold);
  96. void paintVTicks(QPainter &painter, int x, int y, int height);
  97. QMutex dataMutex;
  98. uint64_t currentLastUpdateTime = 0;
  99. float currentMagnitude[MAX_AUDIO_CHANNELS];
  100. float currentPeak[MAX_AUDIO_CHANNELS];
  101. float currentInputPeak[MAX_AUDIO_CHANNELS];
  102. QPixmap *tickPaintCache = nullptr;
  103. int displayNrAudioChannels = 0;
  104. float displayMagnitude[MAX_AUDIO_CHANNELS];
  105. float displayPeak[MAX_AUDIO_CHANNELS];
  106. float displayPeakHold[MAX_AUDIO_CHANNELS];
  107. uint64_t displayPeakHoldLastUpdateTime[MAX_AUDIO_CHANNELS];
  108. float displayInputPeakHold[MAX_AUDIO_CHANNELS];
  109. uint64_t displayInputPeakHoldLastUpdateTime[MAX_AUDIO_CHANNELS];
  110. QFont tickFont;
  111. QColor backgroundNominalColor;
  112. QColor backgroundWarningColor;
  113. QColor backgroundErrorColor;
  114. QColor foregroundNominalColor;
  115. QColor foregroundWarningColor;
  116. QColor foregroundErrorColor;
  117. QColor clipColor;
  118. QColor magnitudeColor;
  119. QColor majorTickColor;
  120. QColor minorTickColor;
  121. qreal minimumLevel;
  122. qreal warningLevel;
  123. qreal errorLevel;
  124. qreal clipLevel;
  125. qreal minimumInputLevel;
  126. qreal peakDecayRate;
  127. qreal magnitudeIntegrationTime;
  128. qreal peakHoldDuration;
  129. qreal inputPeakHoldDuration;
  130. uint64_t lastRedrawTime = 0;
  131. int channels = 0;
  132. bool clipping = false;
  133. bool vertical;
  134. public:
  135. explicit VolumeMeter(QWidget *parent = nullptr,
  136. obs_volmeter_t *obs_volmeter = nullptr,
  137. bool vertical = false);
  138. ~VolumeMeter();
  139. void setLevels(
  140. const float magnitude[MAX_AUDIO_CHANNELS],
  141. const float peak[MAX_AUDIO_CHANNELS],
  142. const float inputPeak[MAX_AUDIO_CHANNELS]);
  143. QColor getBackgroundNominalColor() const;
  144. void setBackgroundNominalColor(QColor c);
  145. QColor getBackgroundWarningColor() const;
  146. void setBackgroundWarningColor(QColor c);
  147. QColor getBackgroundErrorColor() const;
  148. void setBackgroundErrorColor(QColor c);
  149. QColor getForegroundNominalColor() const;
  150. void setForegroundNominalColor(QColor c);
  151. QColor getForegroundWarningColor() const;
  152. void setForegroundWarningColor(QColor c);
  153. QColor getForegroundErrorColor() const;
  154. void setForegroundErrorColor(QColor c);
  155. QColor getClipColor() const;
  156. void setClipColor(QColor c);
  157. QColor getMagnitudeColor() const;
  158. void setMagnitudeColor(QColor c);
  159. QColor getMajorTickColor() const;
  160. void setMajorTickColor(QColor c);
  161. QColor getMinorTickColor() const;
  162. void setMinorTickColor(QColor c);
  163. qreal getMinimumLevel() const;
  164. void setMinimumLevel(qreal v);
  165. qreal getWarningLevel() const;
  166. void setWarningLevel(qreal v);
  167. qreal getErrorLevel() const;
  168. void setErrorLevel(qreal v);
  169. qreal getClipLevel() const;
  170. void setClipLevel(qreal v);
  171. qreal getMinimumInputLevel() const;
  172. void setMinimumInputLevel(qreal v);
  173. qreal getPeakDecayRate() const;
  174. void setPeakDecayRate(qreal v);
  175. qreal getMagnitudeIntegrationTime() const;
  176. void setMagnitudeIntegrationTime(qreal v);
  177. qreal getPeakHoldDuration() const;
  178. void setPeakHoldDuration(qreal v);
  179. qreal getInputPeakHoldDuration() const;
  180. void setInputPeakHoldDuration(qreal v);
  181. void setPeakMeterType(enum obs_peak_meter_type peakMeterType);
  182. virtual void mousePressEvent(QMouseEvent *event) override;
  183. virtual void wheelEvent(QWheelEvent *event) override;
  184. virtual void leaveEvent(QEvent *event) override;
  185. protected:
  186. void paintEvent(QPaintEvent *event) override;
  187. };
  188. class VolumeMeterTimer : public QTimer {
  189. Q_OBJECT
  190. public:
  191. inline VolumeMeterTimer() : QTimer() {}
  192. void AddVolControl(VolumeMeter *meter);
  193. void RemoveVolControl(VolumeMeter *meter);
  194. protected:
  195. void timerEvent(QTimerEvent *event) override;
  196. QList<VolumeMeter*> volumeMeters;
  197. };
  198. class QLabel;
  199. class QSlider;
  200. class MuteCheckBox;
  201. class VolControl : public QWidget {
  202. Q_OBJECT
  203. private:
  204. OBSSource source;
  205. QLabel *nameLabel;
  206. QLabel *volLabel;
  207. VolumeMeter *volMeter;
  208. QSlider *slider;
  209. MuteCheckBox *mute;
  210. QPushButton *config = nullptr;
  211. float levelTotal;
  212. float levelCount;
  213. obs_fader_t *obs_fader;
  214. obs_volmeter_t *obs_volmeter;
  215. bool vertical;
  216. static void OBSVolumeChanged(void *param, float db);
  217. static void OBSVolumeLevel(void *data,
  218. const float magnitude[MAX_AUDIO_CHANNELS],
  219. const float peak[MAX_AUDIO_CHANNELS],
  220. const float inputPeak[MAX_AUDIO_CHANNELS]);
  221. static void OBSVolumeMuted(void *data, calldata_t *calldata);
  222. void EmitConfigClicked();
  223. private slots:
  224. void VolumeChanged();
  225. void VolumeMuted(bool muted);
  226. void SetMuted(bool checked);
  227. void SliderChanged(int vol);
  228. void updateText();
  229. signals:
  230. void ConfigClicked();
  231. public:
  232. explicit VolControl(OBSSource source, bool showConfig = false,
  233. bool vertical = false);
  234. ~VolControl();
  235. inline obs_source_t *GetSource() const {return source;}
  236. QString GetName() const;
  237. void SetName(const QString &newName);
  238. void SetMeterDecayRate(qreal q);
  239. void setPeakMeterType(enum obs_peak_meter_type peakMeterType);
  240. };