File: qdbmeter.py

package info (click to toggle)
linux-show-player 0.5.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,896 kB
  • sloc: python: 12,408; sh: 154; makefile: 17; xml: 8
file content (139 lines) | stat: -rw-r--r-- 4,725 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# -*- coding: utf-8 -*-
#
# This file is part of Linux Show Player
#
# Copyright 2012-2016 Francesco Ceruti <ceppofrancy@gmail.com>
#
# Linux Show Player is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Linux Show Player is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Linux Show Player.  If not, see <http://www.gnu.org/licenses/>.

from PyQt5 import QtCore
from PyQt5.QtGui import QLinearGradient, QColor, QPainter
from PyQt5.QtWidgets import QWidget

from lisp.core.configuration import config
from lisp.core.decorators import suppress_exceptions


class QDbMeter(QWidget):
    DB_MIN = int(config["DbMeter"]["dbMin"])
    DB_MAX = int(config["DbMeter"]["dbMax"])
    DB_CLIP = int(config["DbMeter"]["dbClip"])

    def __init__(self, parent):
        super().__init__(parent)

        db_range = abs(self.DB_MIN - self.DB_MAX)
        yellow = abs(self.DB_MIN + 20) / db_range  # -20 db
        red = abs(self.DB_MIN) / db_range          # 0 db

        self.grad = QLinearGradient()
        self.grad.setColorAt(0, QColor(0, 255, 0))            # Green
        self.grad.setColorAt(yellow, QColor(255, 255, 0))     # Yellow
        self.grad.setColorAt(red, QColor(255, 0, 0))          # Red

        self.reset()

    def reset(self):
        self.peaks = [self.DB_MIN, self.DB_MIN]
        self.rmss = [self.DB_MIN, self.DB_MIN]
        self.decPeak = [self.DB_MIN, self.DB_MIN]
        self.clipping = {}
        self.repaint()

    def plot(self, peaks, rms, decPeak):
        self.peaks = peaks
        self.rmss = rms
        self.decPeak = decPeak

        self.repaint()

    @suppress_exceptions
    def paintEvent(self, e):
        if not self.visibleRegion().isEmpty():
            # Stretch factor
            mul = (self.height() - 4)
            mul /= (self.DB_MAX - self.DB_MIN)

            peaks = []
            for n, peak in enumerate(self.peaks):
                if peak > self.DB_CLIP:
                    self.clipping[n] = True

                if peak < self.DB_MIN:
                    peak = self.DB_MIN
                elif peak > self.DB_MAX:
                    peak = self.DB_MAX

                peaks.append(round((peak - self.DB_MIN) * mul))

            rmss = []
            for n, rms in enumerate(self.rmss):
                if rms < self.DB_MIN:
                    rms = self.DB_MIN
                elif rms > self.DB_MAX:
                    rms = self.DB_MAX

                rmss.append(round((rms - self.DB_MIN) * mul))

            dPeaks = []
            for dPeak in self.decPeak:
                if dPeak < self.DB_MIN:
                    dPeak = self.DB_MIN
                elif dPeak > self.DB_MAX:
                    dPeak = self.DB_MAX

                dPeaks.append(round((dPeak - self.DB_MIN) * mul))

            qp = QPainter()
            qp.begin(self)
            qp.setBrush(QColor(0, 0, 0, 0))

            xpos = 0
            xdim = self.width() / len(peaks)

            for n, (peak, rms, dPeak) in enumerate(zip(peaks, rmss, dPeaks)):
                # Maximum "peak-rect" size
                maxRect = QtCore.QRectF(xpos, self.height() - 2, xdim - 2,
                                       2 - self.height())

                # Set QLinearGradient start and final-stop position
                self.grad.setStart(maxRect.topLeft())
                self.grad.setFinalStop(maxRect.bottomRight())

                # Draw peak (audio peak in dB)
                rect = QtCore.QRectF(xpos, self.height() - 2, xdim - 2, -peak)
                qp.setOpacity(0.6)
                qp.fillRect(rect, self.grad)
                qp.setOpacity(1.0)

                # Draw rms (in db)
                rect = QtCore.QRectF(xpos, self.height() - 2, xdim - 2, -rms)
                qp.fillRect(rect, self.grad)

                # Draw decay peak
                decRect = QtCore.QRectF(xpos, (self.height() - 3) - dPeak,
                                       xdim - 2, 2)
                qp.fillRect(decRect, self.grad)

                # Draw Borders
                if self.clipping.get(n, False):
                    qp.setPen(QColor(200, 0, 0))
                else:
                    qp.setPen(QColor(100, 100, 100))

                qp.drawRect(maxRect)

                xpos += xdim

            qp.end()