]> git.0d.be Git - jack_mixer.git/blob - scale.py
Set version to 14 in preparation for next release
[jack_mixer.git] / scale.py
1 # This file is part of jack_mixer
2 #
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
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; version 2 of the License
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 import logging
19 import math
20
21 import jack_mixer_c
22
23
24 log = logging.getLogger(__name__)
25
26
27 class Mark:
28     '''Encapsulates scale linear function edge and coefficients for scale = a * dB + b formula'''
29     def __init__(self, db, scale):
30         self.db = db
31         self.scale = scale
32         self.text = "%.0f" % math.fabs(db)
33
34
35 class Base:
36     '''Scale abstraction, various scale implementation derive from this class'''
37     def __init__(self, scale_id, description):
38         self.marks = []
39         self.scale_id = scale_id
40         self.description = description
41         self.scale = jack_mixer_c.Scale()
42
43     def add_threshold(self, db, scale, is_mark):
44         self.scale.add_threshold(db, scale)
45         if is_mark:
46             self.marks.append(Mark(db, scale))
47
48     def calculate_coefficients(self):
49         self.scale.calculate_coefficients()
50
51     def db_to_scale(self, db):
52         '''Convert dBFS value to number in range 0.0-1.0 used in GUI'''
53         log.debug("db_to_scale(%f)", db)
54         return self.scale.db_to_scale(db)
55
56     def scale_to_db(self, scale):
57         '''Convert number in range 0.0-1.0 used in GUI to dBFS value'''
58         return self.scale.scale_to_db(scale)
59
60     def add_mark(self, db):
61         self.marks.append(Mark(db, -1.0))
62
63     def get_marks(self):
64         return self.marks
65
66     def scale_marks(self):
67         for i in self.marks:
68             if i.scale == -1.0:
69                 i.scale = self.db_to_scale(i.db)
70
71
72 # IEC 60268-18 Peak programme level meters - Digital audio peak level meter
73 # Adapted from meterbridge, may be wrong, I'm not buying standards, event if they cost $45
74 # If someone has the standard, please either share it with me or fix the code.
75 class IEC268(Base):
76     '''IEC 60268-18 Peak programme level meters - Digital audio peak level meter'''
77     def __init__(self):
78         Base.__init__(self, "iec_268",
79                       "IEC 60268-18 Peak programme level meters - Digital audio peak level meter")
80         self.add_threshold(-70.0, 0.0, False)
81         self.add_threshold(-60.0, 0.05, True)
82         self.add_threshold(-50.0, 0.075, True)
83         self.add_threshold(-40.0, 0.15, True)
84         self.add_mark(-35.0)
85         self.add_threshold(-30.0, 0.3, True)
86         self.add_mark(-25.0)
87         self.add_threshold(-20.0, 0.5, True)
88         self.add_mark(-15.0)
89         self.add_mark(-10.0)
90         self.add_mark(-5.0)
91         self.add_threshold(0.0, 1.0, True)
92         self.calculate_coefficients()
93         self.scale_marks()
94
95
96 class IEC268Minimalistic(Base):
97     '''IEC 60268-18 Peak programme level meters - Digital audio peak level meter,
98        fewer marks'''
99     def __init__(self):
100         Base.__init__(self, 'iec_268_minimalistic',
101                       'IEC 60268-18 Peak programme level meters - Digital audio peak level meter, fewer marks')
102         self.add_threshold(-70.0, 0.0, False)
103         self.add_threshold(-60.0, 0.05, True)
104         self.add_threshold(-50.0, 0.075, False)
105         self.add_threshold(-40.0, 0.15, True)
106         self.add_threshold(-30.0, 0.3, True)
107         self.add_threshold(-20.0, 0.5, True)
108         self.add_mark(-10.0)
109         self.add_threshold(0.0, 1.0, True)
110         self.calculate_coefficients()
111         self.scale_marks()
112
113
114 class Linear70dB(Base):
115     '''Linear scale with range from -70 to 0 dBFS'''
116     def __init__(self):
117         Base.__init__(self, "linear_70dB", "Linear scale with range from -70 to 0 dBFS")
118         self.add_threshold(-70.0, 0.0, False)
119         self.add_mark(-60.0)
120         self.add_mark(-50.0)
121         self.add_mark(-40.0)
122         self.add_mark(-35.0)
123         self.add_mark(-30.0)
124         self.add_mark(-25.0)
125         self.add_mark(-20.0)
126         self.add_mark(-15.0)
127         self.add_mark(-10.0)
128         self.add_mark(-5.0)
129         self.add_threshold(0.0, 1.0, True)
130         self.calculate_coefficients()
131         self.scale_marks()
132
133
134 class Linear30dB(Base):
135     '''Linear scale with range from -30 to +30 dBFS'''
136     def __init__(self):
137         Base.__init__(self, "linear_30dB", "Linear scale with range from -30 to +30 dBFS")
138         self.add_threshold(-30.0, 0.0, False)
139         self.add_threshold(+30.0, 1.0, True)
140         self.calculate_coefficients()
141         self.scale_marks()
142
143
144 def scale_test1(scale):
145     for i in range(-97 * 2, 1, 1):
146         db = float(i)/2.0
147         print("%5.1f dB maps to %f" % (db, scale.db_to_scale(db)))
148
149
150 def scale_test2(scale):
151     for i in range(101):
152         s = float(i)/100.0
153         print("%.2f maps to %.1f dB" % (s, scale.scale_to_db(s)))
154
155
156 def print_db_to_scale(scale, db):
157     print("%-.1f dB maps to %f" % (db, scale.db_to_scale(db)))
158
159
160 def scale_test3(scale):
161     print_db_to_scale(scale, +77.0)
162     print_db_to_scale(scale, +7.0)
163     print_db_to_scale(scale, 0.0)
164     print_db_to_scale(scale, -107.0)
165
166
167 def _test(*args, **kwargs):
168     scale = Linear30dB()
169     scale_test1(scale)
170     scale_test2(scale)
171     scale_test3(scale)
172
173
174 if __name__ == '__main__':
175     _test()