volume-control.hpp 8.1 KB

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