volume-control.hpp 7.3 KB

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