1 # This file is part of jack_mixer
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
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
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.
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.
24 log
= logging
.getLogger(__name__
)
28 """Encapsulates scale linear function edge and coefficients for scale = a * dB + b formula"""
30 def __init__(self
, db
, scale
, text
=None):
34 self
.text
= "%.0f" % math
.fabs(db
)
40 """Scale abstraction, various scale implementation derive from this class"""
42 def __init__(self
, scale_id
, description
):
44 self
.scale_id
= scale_id
45 self
.description
= description
46 self
.scale
= jack_mixer_c
.Scale()
48 def add_threshold(self
, db
, scale
, is_mark
, text
=None):
49 self
.scale
.add_threshold(db
, scale
)
51 self
.marks
.append(Mark(db
, scale
, text
))
53 def calculate_coefficients(self
):
54 self
.scale
.calculate_coefficients()
56 def db_to_scale(self
, db
):
57 """Convert dBFS value to number in range 0.0-1.0 used in GUI"""
58 # log.debug("db_to_scale(%f)", db)
59 return self
.scale
.db_to_scale(db
)
61 def scale_to_db(self
, scale
):
62 """Convert number in range 0.0-1.0 used in GUI to dBFS value"""
63 return self
.scale
.scale_to_db(scale
)
65 def add_mark(self
, db
):
66 self
.marks
.append(Mark(db
, -1.0))
71 def scale_marks(self
):
74 i
.scale
= self
.db_to_scale(i
.db
)
77 # IEC 60268-18 Peak programme level meters - Digital audio peak level meter
78 # Adapted from meterbridge, may be wrong, I'm not buying standards, event if they cost $45
79 # If someone has the standard, please either share it with me or fix the code.
81 """IEC 60268-18 Peak programme level meters - Digital audio peak level meter"""
87 "IEC 60268-18 Peak programme level meters - Digital audio peak level meter",
89 self
.add_threshold(-70.0, 0.0, False)
90 self
.add_threshold(-60.0, 0.05, True)
91 self
.add_threshold(-50.0, 0.075, True)
92 self
.add_threshold(-40.0, 0.15, True)
94 self
.add_threshold(-30.0, 0.3, True)
96 self
.add_threshold(-20.0, 0.5, True)
100 self
.add_threshold(0.0, 1.0, True)
101 self
.calculate_coefficients()
105 class IEC268Minimalistic(Base
):
106 """IEC 60268-18 Peak programme level meters - Digital audio peak level meter,
112 "iec_268_minimalistic",
113 "IEC 60268-18 Peak programme level meters - "
114 "Digital audio peak level meter, fewer marks",
116 self
.add_threshold(-70.0, 0.0, False)
117 self
.add_threshold(-60.0, 0.05, True)
118 self
.add_threshold(-50.0, 0.075, False)
119 self
.add_threshold(-40.0, 0.15, True)
120 self
.add_threshold(-30.0, 0.3, True)
121 self
.add_threshold(-20.0, 0.5, True)
123 self
.add_threshold(0.0, 1.0, True)
124 self
.calculate_coefficients()
128 class Linear70dB(Base
):
129 """Linear scale with range from -70 to 0 dBFS"""
132 Base
.__init
__(self
, "linear_70dB", "Linear scale with range from -70 to 0 dBFS")
133 self
.add_threshold(-70.0, 0.0, False)
144 self
.add_threshold(0.0, 1.0, True)
145 self
.calculate_coefficients()
149 class Linear30dB(Base
):
150 """Linear scale with range from -30 to +30 dBFS"""
153 Base
.__init
__(self
, "linear_30dB", "Linear scale with range from -30 to +30 dBFS")
154 self
.add_threshold(-30.0, 0.0, False)
155 self
.add_threshold(+30.0, 1.0, True)
156 self
.calculate_coefficients()
164 Base
.__init
__(self
, "K20", "K20 scale")
165 self
.add_mark(-200, "")
166 self
.add_mark(-60, "-40")
167 self
.add_mark(-55, "")
168 self
.add_mark(-50, "-30")
169 self
.add_mark(-45, "")
170 self
.add_mark(-40, "-20")
171 self
.add_mark(-35, "")
172 self
.add_mark(-30, "-10")
173 self
.add_mark(-26, "-6")
174 self
.add_mark(-23, "-3")
175 self
.add_mark(-20, "0")
176 self
.add_mark(-17, "3")
177 self
.add_mark(-14, "6")
178 self
.add_mark(-10, "10")
179 self
.add_mark(-5, "15")
180 self
.add_mark(0, "20")
182 def db_to_scale(self
, db
):
183 v
= math
.pow(10.0, db
/ 20.0)
184 return self
.mapk20(v
) / 450.0
186 def add_mark(self
, db
, text
):
187 self
.marks
.append(Mark(db
, self
.db_to_scale(db
), text
))
192 v
= math
.log10(v
) + 3
194 return 24.3 + v
* (100 + v
* 16)
197 return v
* 161.7 - 35.1
204 Base
.__init
__(self
, "K14", "K14 scale")
205 self
.add_mark(-200, "")
206 self
.add_mark(-54, "-40")
207 self
.add_mark(-35 - 14, "")
208 self
.add_mark(-30 - 14, "-30")
209 self
.add_mark(-25 - 14, "")
210 self
.add_mark(-20 - 14, "-20")
211 self
.add_mark(-15 - 14, "")
212 self
.add_mark(-10 - 14, "-10")
213 self
.add_mark(-6 - 14, "-6")
214 self
.add_mark(-3 - 14, "-3")
215 self
.add_mark(-14, "0")
216 self
.add_mark(3 - 14, "3")
217 self
.add_mark(6 - 14, "6")
218 self
.add_mark(10 - 14, "10")
219 self
.add_mark(14 - 14, "14")
221 def db_to_scale(self
, db
):
222 v
= math
.pow(10.0, db
/ 20.0)
223 return self
.mapk14(v
) / 448.3
225 def add_mark(self
, db
, text
):
226 self
.marks
.append(Mark(db
, self
.db_to_scale(db
), text
))
230 return int(12000 * v
)
231 v
= math
.log10(v
) + 2.7
233 return int(20.3 + v
* (80 + v
* 32))
236 return int(v
* 200 - 91.7)
239 def scale_test1(scale
):
240 for i
in range(-97 * 2, 1, 1):
242 print("%5.1f dB maps to %f" % (db
, scale
.db_to_scale(db
)))
245 def scale_test2(scale
):
248 print("%.2f maps to %.1f dB" % (s
, scale
.scale_to_db(s
)))
251 def print_db_to_scale(scale
, db
):
252 print("%-.1f dB maps to %f" % (db
, scale
.db_to_scale(db
)))
255 def scale_test3(scale
):
256 print_db_to_scale(scale
, +77.0)
257 print_db_to_scale(scale
, +7.0)
258 print_db_to_scale(scale
, 0.0)
259 print_db_to_scale(scale
, -107.0)
262 def _test(*args
, **kwargs
):
269 if __name__
== "__main__":