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'''
29 def __init__(self, db, scale, text = None):
33 self.text = "%.0f" % math.fabs(db)
38 '''Scale abstraction, various scale implementation derive from this class'''
39 def __init__(self, scale_id, description):
41 self.scale_id = scale_id
42 self.description = description
43 self.scale = jack_mixer_c.Scale()
45 def add_threshold(self, db, scale, is_mark, text = None):
46 self.scale.add_threshold(db, scale)
48 self.marks.append(Mark(db, scale, text))
50 def calculate_coefficients(self):
51 self.scale.calculate_coefficients()
53 def db_to_scale(self, db):
54 '''Convert dBFS value to number in range 0.0-1.0 used in GUI'''
55 #log.debug("db_to_scale(%f)", db)
56 return self.scale.db_to_scale(db)
58 def scale_to_db(self, scale):
59 '''Convert number in range 0.0-1.0 used in GUI to dBFS value'''
60 return self.scale.scale_to_db(scale)
62 def add_mark(self, db):
63 self.marks.append(Mark(db, -1.0))
68 def scale_marks(self):
71 i.scale = self.db_to_scale(i.db)
74 # IEC 60268-18 Peak programme level meters - Digital audio peak level meter
75 # Adapted from meterbridge, may be wrong, I'm not buying standards, event if they cost $45
76 # If someone has the standard, please either share it with me or fix the code.
78 '''IEC 60268-18 Peak programme level meters - Digital audio peak level meter'''
80 Base.__init__(self, "iec_268",
81 "IEC 60268-18 Peak programme level meters - Digital audio peak level meter")
82 self.add_threshold(-70.0, 0.0, False)
83 self.add_threshold(-60.0, 0.05, True)
84 self.add_threshold(-50.0, 0.075, True)
85 self.add_threshold(-40.0, 0.15, True)
87 self.add_threshold(-30.0, 0.3, True)
89 self.add_threshold(-20.0, 0.5, True)
93 self.add_threshold(0.0, 1.0, True)
94 self.calculate_coefficients()
98 class IEC268Minimalistic(Base):
99 '''IEC 60268-18 Peak programme level meters - Digital audio peak level meter,
102 Base.__init__(self, 'iec_268_minimalistic',
103 'IEC 60268-18 Peak programme level meters - Digital audio peak level meter, fewer marks')
104 self.add_threshold(-70.0, 0.0, False)
105 self.add_threshold(-60.0, 0.05, True)
106 self.add_threshold(-50.0, 0.075, False)
107 self.add_threshold(-40.0, 0.15, True)
108 self.add_threshold(-30.0, 0.3, True)
109 self.add_threshold(-20.0, 0.5, True)
111 self.add_threshold(0.0, 1.0, True)
112 self.calculate_coefficients()
116 class Linear70dB(Base):
117 '''Linear scale with range from -70 to 0 dBFS'''
119 Base.__init__(self, "linear_70dB", "Linear scale with range from -70 to 0 dBFS")
120 self.add_threshold(-70.0, 0.0, False)
131 self.add_threshold(0.0, 1.0, True)
132 self.calculate_coefficients()
136 class Linear30dB(Base):
137 '''Linear scale with range from -30 to +30 dBFS'''
139 Base.__init__(self, "linear_30dB", "Linear scale with range from -30 to +30 dBFS")
140 self.add_threshold(-30.0, 0.0, False)
141 self.add_threshold(+30.0, 1.0, True)
142 self.calculate_coefficients()
148 Base.__init__(self, "K20", "K20 scale")
149 self.add_mark(-200, "")
150 self.add_mark(-60, "-40")
151 self.add_mark(-55, "")
152 self.add_mark(-50, "-30")
153 self.add_mark(-45, "")
154 self.add_mark(-40, "-20")
155 self.add_mark(-35, "")
156 self.add_mark(-30, "-10")
157 self.add_mark(-26, "-6")
158 self.add_mark(-23, "-3")
159 self.add_mark(-20, "0")
160 self.add_mark(-17, "3")
161 self.add_mark(-14, "6")
162 self.add_mark(-10, "10")
163 self.add_mark(-5, "15")
164 self.add_mark(0, "20")
166 def db_to_scale(self, db):
167 v = math.pow(10.0, db/20.0)
168 return self.mapk20(v)/450.0
170 def add_mark(self, db, text):
171 self.marks.append(Mark(db, self.db_to_scale(db), text))
174 if v < 0.001: return (24000 * v)
175 v = math.log10(v) + 3
176 if v < 2.0: return (24.3 + v * (100 + v * 16))
178 return (v * 161.7 - 35.1)
184 Base.__init__(self, "K14", "K14 scale")
185 self.add_mark(-200, "")
186 self.add_mark(-54, "-40")
187 self.add_mark(-35-14, "")
188 self.add_mark(-30-14, "-30")
189 self.add_mark(-25-14, "")
190 self.add_mark(-20-14, "-20")
191 self.add_mark(-15-14, "")
192 self.add_mark(-10-14, "-10")
193 self.add_mark(-6-14, "-6")
194 self.add_mark(-3-14, "-3")
195 self.add_mark(-14, "0")
196 self.add_mark(3-14, "3")
197 self.add_mark(6-14, "6")
198 self.add_mark(10-14, "10")
199 self.add_mark(14-14, "14")
201 def db_to_scale(self, db):
202 v = math.pow(10.0, db/20.0)
203 return self.mapk14(v)/448.3
205 def add_mark(self, db, text):
206 self.marks.append(Mark(db, self.db_to_scale(db), text))
209 if v < 0.002: return int(12000 * v);
210 v = math.log10(v) + 2.7;
211 if v < 2.0: return int(20.3 + v * (80 + v * 32));
213 return int(v * 200 - 91.7);
215 def scale_test1(scale):
216 for i in range(-97 * 2, 1, 1):
218 print("%5.1f dB maps to %f" % (db, scale.db_to_scale(db)))
221 def scale_test2(scale):
224 print("%.2f maps to %.1f dB" % (s, scale.scale_to_db(s)))
227 def print_db_to_scale(scale, db):
228 print("%-.1f dB maps to %f" % (db, scale.db_to_scale(db)))
231 def scale_test3(scale):
232 print_db_to_scale(scale, +77.0)
233 print_db_to_scale(scale, +7.0)
234 print_db_to_scale(scale, 0.0)
235 print_db_to_scale(scale, -107.0)
238 def _test(*args, **kwargs):
245 if __name__ == '__main__':