Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

271 lines
7.3KB

  1. /*
  2. * Digital Peak Meter, a custom Qt4 widget
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #include "digitalpeakmeter.hpp"
  18. #include <QtGui/QPainter>
  19. DigitalPeakMeter::DigitalPeakMeter(QWidget* parent)
  20. : QWidget(parent),
  21. m_paintTimer(this)
  22. {
  23. m_channels = 0;
  24. m_orientation = VERTICAL;
  25. m_smoothMultiplier = 1;
  26. m_colorBackground = QColor("#111111");
  27. m_gradientMeter = QLinearGradient(0, 0, 1, 1);
  28. setChannels(0);
  29. setColor(GREEN);
  30. m_paintTimer.setInterval(60);
  31. connect(&m_paintTimer, SIGNAL(timeout()), this, SLOT(update()));
  32. m_paintTimer.start();
  33. }
  34. void DigitalPeakMeter::displayMeter(int meter, float level)
  35. {
  36. Q_ASSERT(meter > 0 && meter <= m_channels);
  37. if (meter <= 0 || meter > m_channels)
  38. return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number", meter, level);
  39. if (level < 0.0f)
  40. level = -level;
  41. else if (level > 1.0f)
  42. level = 1.0f;
  43. m_channelsData[meter-1] = level;
  44. }
  45. void DigitalPeakMeter::setChannels(int channels)
  46. {
  47. Q_ASSERT(channels >= 0);
  48. if (channels < 0)
  49. return qCritical("DigitalPeakMeter::setChannels(%i) - 'channels' must be a positive integer", channels);
  50. m_channels = channels;
  51. m_channelsData.clear();
  52. m_lastValueData.clear();
  53. for (int i=0; i < channels; i++)
  54. {
  55. m_channelsData.append(0.0f);
  56. m_lastValueData.append(0.0f);
  57. }
  58. }
  59. void DigitalPeakMeter::setColor(Color color)
  60. {
  61. if (color == GREEN)
  62. {
  63. m_colorBase = QColor(93, 231, 61);
  64. m_colorBaseT = QColor(15, 110, 15, 100);
  65. }
  66. else if (color == BLUE)
  67. {
  68. m_colorBase = QColor(82, 238, 248);
  69. m_colorBaseT = QColor(15, 15, 110, 100);
  70. }
  71. else
  72. return qCritical("DigitalPeakMeter::setColor(%i) - invalid color", color);
  73. setOrientation(m_orientation);
  74. }
  75. void DigitalPeakMeter::setOrientation(Orientation orientation)
  76. {
  77. m_orientation = orientation;
  78. if (m_orientation == HORIZONTAL)
  79. {
  80. m_gradientMeter.setColorAt(0.0f, m_colorBase);
  81. m_gradientMeter.setColorAt(0.2f, m_colorBase);
  82. m_gradientMeter.setColorAt(0.4f, m_colorBase);
  83. m_gradientMeter.setColorAt(0.6f, m_colorBase);
  84. m_gradientMeter.setColorAt(0.8f, Qt::yellow);
  85. m_gradientMeter.setColorAt(1.0f, Qt::red);
  86. }
  87. else if (m_orientation == VERTICAL)
  88. {
  89. m_gradientMeter.setColorAt(0.0f, Qt::red);
  90. m_gradientMeter.setColorAt(0.2f, Qt::yellow);
  91. m_gradientMeter.setColorAt(0.4f, m_colorBase);
  92. m_gradientMeter.setColorAt(0.6f, m_colorBase);
  93. m_gradientMeter.setColorAt(0.8f, m_colorBase);
  94. m_gradientMeter.setColorAt(1.0f, m_colorBase);
  95. }
  96. else
  97. return qCritical("DigitalPeakMeter::setOrientation(%i) - invalid orientation", orientation);
  98. updateSizes();
  99. }
  100. void DigitalPeakMeter::setRefreshRate(int rate)
  101. {
  102. Q_ASSERT(rate > 0);
  103. m_paintTimer.stop();
  104. m_paintTimer.setInterval(rate);
  105. m_paintTimer.start();
  106. }
  107. void DigitalPeakMeter::setSmoothRelease(int value)
  108. {
  109. Q_ASSERT(value >= 0 && value <= 5);
  110. if (value < 0)
  111. value = 0;
  112. else if (value > 5)
  113. value = 5;
  114. m_smoothMultiplier = value;
  115. }
  116. QSize DigitalPeakMeter::minimumSizeHint() const
  117. {
  118. return QSize(30, 30);
  119. }
  120. QSize DigitalPeakMeter::sizeHint() const
  121. {
  122. return QSize(m_width, m_height);
  123. }
  124. void DigitalPeakMeter::updateSizes()
  125. {
  126. m_width = width();
  127. m_height = height();
  128. m_sizeMeter = 0;
  129. if (m_orientation == HORIZONTAL)
  130. {
  131. m_gradientMeter.setFinalStop(m_width, 0);
  132. if (m_channels > 0)
  133. m_sizeMeter = m_height/m_channels;
  134. }
  135. else if (m_orientation == VERTICAL)
  136. {
  137. m_gradientMeter.setFinalStop(0, m_height);
  138. if (m_channels > 0)
  139. m_sizeMeter = m_width/m_channels;
  140. }
  141. }
  142. void DigitalPeakMeter::paintEvent(QPaintEvent*)
  143. {
  144. QPainter painter(this);
  145. painter.setPen(Qt::black);
  146. painter.setBrush(Qt::black);
  147. painter.drawRect(0, 0, m_width, m_height);
  148. int meterX = 0;
  149. painter.setPen(m_colorBackground);
  150. painter.setBrush(m_gradientMeter);
  151. for (int i=0; i < m_channels; i++)
  152. {
  153. float value, level = m_channelsData[i];
  154. if (level == m_lastValueData[i])
  155. continue;
  156. if (m_orientation == HORIZONTAL)
  157. value = level * m_width;
  158. else if (m_orientation == VERTICAL)
  159. value = float(m_height) - (level * m_height);
  160. else
  161. value = 0.0f;
  162. if (value < 0.0f)
  163. value = 0.0f;
  164. else if (m_smoothMultiplier > 0)
  165. value = (m_lastValueData[i] * m_smoothMultiplier + value) / (m_smoothMultiplier + 1);
  166. if (m_orientation == HORIZONTAL)
  167. painter.drawRect(0, meterX, value, m_sizeMeter);
  168. else if (m_orientation == VERTICAL)
  169. painter.drawRect(meterX, value, m_sizeMeter, m_height);
  170. meterX += m_sizeMeter;
  171. m_lastValueData[i] = value;
  172. }
  173. painter.setBrush(QColor(0, 0, 0, 0));
  174. if (m_orientation == HORIZONTAL)
  175. {
  176. // Variables
  177. int lsmall = m_width;
  178. int lfull = m_height - 1;
  179. // Base
  180. painter.setPen(m_colorBaseT);
  181. painter.drawLine(lsmall * 0.25f, 2, lsmall * 0.25f, lfull-2);
  182. painter.drawLine(lsmall * 0.50f, 2, lsmall * 0.50f, lfull-2);
  183. // Yellow
  184. painter.setPen(QColor(110, 110, 15, 100));
  185. painter.drawLine(lsmall * 0.70f, 2, lsmall * 0.70f, lfull-2);
  186. painter.drawLine(lsmall * 0.83f, 2, lsmall * 0.83f, lfull-2);
  187. // Orange
  188. painter.setPen(QColor(180, 110, 15, 100));
  189. painter.drawLine(lsmall * 0.90f, 2, lsmall * 0.90f, lfull-2);
  190. // Red
  191. painter.setPen(QColor(110, 15, 15, 100));
  192. painter.drawLine(lsmall * 0.96f, 2, lsmall * 0.96f, lfull-2);
  193. }
  194. else if (m_orientation == VERTICAL)
  195. {
  196. // Variables
  197. int lsmall = m_height;
  198. int lfull = m_width - 1;
  199. // Base
  200. painter.setPen(m_colorBaseT);
  201. painter.drawLine(2, lsmall - (lsmall * 0.25f), lfull-2, lsmall - (lsmall * 0.25f));
  202. painter.drawLine(2, lsmall - (lsmall * 0.50f), lfull-2, lsmall - (lsmall * 0.50f));
  203. // Yellow
  204. painter.setPen(QColor(110, 110, 15, 100));
  205. painter.drawLine(2, lsmall - (lsmall * 0.70f), lfull-2, lsmall - (lsmall * 0.70f));
  206. painter.drawLine(2, lsmall - (lsmall * 0.83f), lfull-2, lsmall - (lsmall * 0.83f));
  207. // Orange
  208. painter.setPen(QColor(180, 110, 15, 100));
  209. painter.drawLine(2, lsmall - (lsmall * 0.90f), lfull-2, lsmall - (lsmall * 0.90f));
  210. // Red
  211. painter.setPen(QColor(110, 15, 15, 100));
  212. painter.drawLine(2, lsmall - (lsmall * 0.96f), lfull-2, lsmall - (lsmall * 0.96f));
  213. }
  214. }
  215. void DigitalPeakMeter::resizeEvent(QResizeEvent* event)
  216. {
  217. updateSizes();
  218. QWidget::resizeEvent(event);
  219. }