volume-control.hpp 8.0 KB

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