# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+import logging
import math
+
import jack_mixer_c
+
+log = logging.getLogger(__name__)
+
+
class Mark:
'''Encapsulates scale linear function edge and coefficients for scale = a * dB + b formula'''
- def __init__(self, db, scale):
+ def __init__(self, db, scale, text = None):
self.db = db
self.scale = scale
- self.text = "%.0f" % math.fabs(db)
+ if text == None:
+ self.text = "%.0f" % math.fabs(db)
+ else:
+ self.text = text
class Base:
'''Scale abstraction, various scale implementation derive from this class'''
self.description = description
self.scale = jack_mixer_c.Scale()
- def add_threshold(self, db, scale, is_mark):
+ def add_threshold(self, db, scale, is_mark, text = None):
self.scale.add_threshold(db, scale)
if is_mark:
- self.marks.append(Mark(db, scale))
+ self.marks.append(Mark(db, scale, text))
def calculate_coefficients(self):
self.scale.calculate_coefficients()
def db_to_scale(self, db):
'''Convert dBFS value to number in range 0.0-1.0 used in GUI'''
- #print "db_to_scale(%f)" % db
+ #log.debug("db_to_scale(%f)", db)
return self.scale.db_to_scale(db)
def scale_to_db(self, scale):
if i.scale == -1.0:
i.scale = self.db_to_scale(i.db)
+
# IEC 60268-18 Peak programme level meters - Digital audio peak level meter
-# Adapted from meterpridge, may be wrong, I'm not buying standards, event if they cost $45
-# If someone has the standart, please eighter share it with me or fix the code.
+# Adapted from meterbridge, may be wrong, I'm not buying standards, event if they cost $45
+# If someone has the standard, please either share it with me or fix the code.
class IEC268(Base):
'''IEC 60268-18 Peak programme level meters - Digital audio peak level meter'''
def __init__(self):
self.calculate_coefficients()
self.scale_marks()
+
class IEC268Minimalistic(Base):
'''IEC 60268-18 Peak programme level meters - Digital audio peak level meter,
fewer marks'''
self.calculate_coefficients()
self.scale_marks()
+
class Linear70dB(Base):
'''Linear scale with range from -70 to 0 dBFS'''
def __init__(self):
self.calculate_coefficients()
self.scale_marks()
+
class Linear30dB(Base):
'''Linear scale with range from -30 to +30 dBFS'''
def __init__(self):
self.calculate_coefficients()
self.scale_marks()
+class K20(Base):
+ '''K20 scale'''
+ def __init__(self):
+ Base.__init__(self, "K20", "K20 scale")
+ self.add_mark(-200, "")
+ self.add_mark(-60, "-40")
+ self.add_mark(-55, "")
+ self.add_mark(-50, "-30")
+ self.add_mark(-45, "")
+ self.add_mark(-40, "-20")
+ self.add_mark(-35, "")
+ self.add_mark(-30, "-10")
+ self.add_mark(-26, "-6")
+ self.add_mark(-23, "-3")
+ self.add_mark(-20, "0")
+ self.add_mark(-17, "3")
+ self.add_mark(-14, "6")
+ self.add_mark(-10, "10")
+ self.add_mark(-5, "15")
+ self.add_mark(0, "20")
+
+ def db_to_scale(self, db):
+ v = math.pow(10.0, db/20.0)
+ return self.mapk20(v)/450.0
+
+ def add_mark(self, db, text):
+ self.marks.append(Mark(db, self.db_to_scale(db), text))
+
+ def mapk20(self, v):
+ if v < 0.001: return (24000 * v)
+ v = math.log10(v) + 3
+ if v < 2.0: return (24.3 + v * (100 + v * 16))
+ if v > 3.0: v = 3.0
+ return (v * 161.7 - 35.1)
+
+
+class K14(Base):
+ '''K14 scale'''
+ def __init__(self):
+ Base.__init__(self, "K14", "K14 scale")
+ self.add_mark(-200, "")
+ self.add_mark(-54, "-40")
+ self.add_mark(-35-14, "")
+ self.add_mark(-30-14, "-30")
+ self.add_mark(-25-14, "")
+ self.add_mark(-20-14, "-20")
+ self.add_mark(-15-14, "")
+ self.add_mark(-10-14, "-10")
+ self.add_mark(-6-14, "-6")
+ self.add_mark(-3-14, "-3")
+ self.add_mark(-14, "0")
+ self.add_mark(3-14, "3")
+ self.add_mark(6-14, "6")
+ self.add_mark(10-14, "10")
+ self.add_mark(14-14, "14")
+
+ def db_to_scale(self, db):
+ v = math.pow(10.0, db/20.0)
+ return self.mapk14(v)/448.3
+
+ def add_mark(self, db, text):
+ self.marks.append(Mark(db, self.db_to_scale(db), text))
+
+ def mapk14(self, v):
+ if v < 0.002: return int(12000 * v);
+ v = math.log10(v) + 2.7;
+ if v < 2.0: return int(20.3 + v * (80 + v * 32));
+ if v > 2.7: v = 2.7;
+ return int(v * 200 - 91.7);
+
def scale_test1(scale):
for i in range(-97 * 2, 1, 1):
db = float(i)/2.0
- print "%5.1f dB maps to %f" % (db, scale.db_to_scale(db))
+ print("%5.1f dB maps to %f" % (db, scale.db_to_scale(db)))
+
def scale_test2(scale):
for i in range(101):
s = float(i)/100.0
- print "%.2f maps to %.1f dB" % (s, scale.scale_to_db(s))
+ print("%.2f maps to %.1f dB" % (s, scale.scale_to_db(s)))
+
+
+def print_db_to_scale(scale, db):
+ print("%-.1f dB maps to %f" % (db, scale.db_to_scale(db)))
-def print_db_to_scale(db):
- print "%-.1f dB maps to %f" % (db, scale.db_to_scale(db))
def scale_test3(scale):
- print_db_to_scale(+77.0)
- print_db_to_scale(+7.0)
- print_db_to_scale(0.0)
- print_db_to_scale(-107.0)
-
-#scale = linear_30dB()
-#scale_test2(scale)
-#scale_test3(scale)
+ print_db_to_scale(scale, +77.0)
+ print_db_to_scale(scale, +7.0)
+ print_db_to_scale(scale, 0.0)
+ print_db_to_scale(scale, -107.0)
+
+
+def _test(*args, **kwargs):
+ scale = Linear30dB()
+ scale_test1(scale)
+ scale_test2(scale)
+ scale_test3(scale)
+
+
+if __name__ == '__main__':
+ _test()