#include "AudioLevelMeter.h" #include #include AudioLevelMeter::AudioLevelMeter(QWidget *parent) : QWidget(parent) { setAutoFillBackground(false); setAttribute(Qt::WA_OpaquePaintEvent); } void AudioLevelMeter::setLevel(float level) { m_level = std::clamp(level, 0.0f, 1.0f); if (m_level >= m_peakHold) { m_peakHold = m_level; m_peakHoldFrames = 0; } else { ++m_peakHoldFrames; if (m_peakHoldFrames > kPeakHoldDuration) { m_peakHold = std::max(0.0f, m_peakHold - kPeakDecayRate); } } update(); } float AudioLevelMeter::level() const { return m_level; } float AudioLevelMeter::peakHold() const { return m_peakHold; } void AudioLevelMeter::resetPeakHold() { m_peakHold = 0.0f; m_peakHoldFrames = 0; update(); } QSize AudioLevelMeter::sizeHint() const { return {40, 160}; } QSize AudioLevelMeter::minimumSizeHint() const { return {12, 40}; } void AudioLevelMeter::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, false); QRect r = rect(); painter.fillRect(r, QColor(24, 24, 28)); if (m_level <= 0.0f && m_peakHold <= 0.0f) return; int barHeight = static_cast(m_level * r.height()); int barTop = r.height() - barHeight; if (barHeight > 0) { float greenEnd = 0.7f * r.height(); float yellowEnd = 0.9f * r.height(); int greenH = std::min(barHeight, static_cast(greenEnd)); if (greenH > 0) { painter.fillRect(r.left(), r.bottom() - greenH + 1, r.width(), greenH, QColor(76, 175, 80)); } if (barHeight > static_cast(greenEnd)) { int yellowH = std::min(barHeight - static_cast(greenEnd), static_cast(yellowEnd) - static_cast(greenEnd)); if (yellowH > 0) { painter.fillRect(r.left(), r.bottom() - static_cast(greenEnd) - yellowH + 1, r.width(), yellowH, QColor(255, 193, 7)); } } if (barHeight > static_cast(yellowEnd)) { int redH = barHeight - static_cast(yellowEnd); if (redH > 0) { painter.fillRect(r.left(), barTop, r.width(), redH, QColor(244, 67, 54)); } } } if (m_peakHold > 0.0f) { int peakY = r.height() - static_cast(m_peakHold * r.height()); peakY = std::clamp(peakY, r.top(), r.bottom()); painter.setPen(QColor(255, 255, 255)); painter.drawLine(r.left(), peakY, r.right(), peakY); } }