Collection of tools useful for audio production
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.

270 lines
7.3KB

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