aboutsummaryrefslogtreecommitdiff
path: root/voctogui/lib/audioleveldisplay.py
diff options
context:
space:
mode:
authorMaZderMind <git@mazdermind.de>2016-01-29 21:13:22 +0100
committerMaZderMind <git@mazdermind.de>2016-01-29 21:14:24 +0100
commit4037733853ad2dbb0064d68f7590e0c94f98151e (patch)
treeaec724da68bc4896dddbb78d510c69fa55bf7a8f /voctogui/lib/audioleveldisplay.py
parent4ddbb55eac513c1863a453a8d21cd6c8dc167661 (diff)
logarithmic audio display, fixes #28
Diffstat (limited to 'voctogui/lib/audioleveldisplay.py')
-rw-r--r--voctogui/lib/audioleveldisplay.py62
1 files changed, 44 insertions, 18 deletions
diff --git a/voctogui/lib/audioleveldisplay.py b/voctogui/lib/audioleveldisplay.py
index f74c3f5..5aaf088 100644
--- a/voctogui/lib/audioleveldisplay.py
+++ b/voctogui/lib/audioleveldisplay.py
@@ -1,4 +1,4 @@
-import logging
+import logging, math
from gi.repository import Gst, Gtk
class AudioLevelDisplay(object):
@@ -10,6 +10,8 @@ class AudioLevelDisplay(object):
self.drawing_area = drawing_area
self.levelrms = []
+ self.levelpeak = []
+ self.leveldecay = []
self.drawing_area.connect('draw', self.on_draw)
def on_draw(self, widget, cr):
@@ -20,32 +22,56 @@ class AudioLevelDisplay(object):
width = self.drawing_area.get_allocated_width()
height = self.drawing_area.get_allocated_height()
+ margin = 2 # px
- strip_width = int(width / 2)
- #self.log.debug('width: %u, strip_width: %u', width, strip_width)
+ channel_width = int((width - (margin * (channels - 1))) / channels)
+ # self.log.debug(
+ # 'width: %upx filled with %u channels of each %upx '
+ # 'and %ux margin of %upx',
+ # width, channels, channel_width, channels-1, margin)
- cr.set_line_width(strip_width)
+ rms_px = [ self.normalize_db(db) * height for db in self.levelrms ]
+ peak_px = [ self.normalize_db(db) * height for db in self.levelpeak ]
+ decay_px = [ self.normalize_db(db) * height for db in self.leveldecay ]
- maxdb = -75
+ cr.set_line_width(channel_width)
+ for y in range(0, height):
+ pct = y / height
- for idx, level in enumerate(self.levelrms):
- level = level / maxdb
+ for channel in range(0, channels):
+ x = (channel * channel_width) + (channel * margin)
- x = idx * strip_width + strip_width/2
- #self.log.debug('x: %u', x)
+ bright = 0.25
+ if y < rms_px[channel]:
+ bright = 1
+ # elif abs(y - peak_px[channel]) < 3:
+ # bright = 1.5
+ elif y < decay_px[channel]:
+ bright = 0.75
- cr.move_to(x, height)
- cr.line_to(x, height * level)
+ cr.set_source_rgb(pct * bright, (1-pct) * bright, 0 * bright)
- if idx % 2 == 0:
- cr.set_source_rgb(1, 0, 0)
- else:
- cr.set_source_rgb(0, 1, 0)
-
- cr.stroke()
+ cr.move_to(x, height-y)
+ cr.line_to(x + channel_width, height-y)
+ cr.stroke()
return True
- def level_callback(self, peaks, rms):
+ def normalize_db(self, db):
+ # -60db -> 1.00 (very quiet)
+ # -30db -> 0.75
+ # -15db -> 0.50
+ # -5db -> 0.25
+ # -0db -> 0.00 (very loud)
+ logscale = math.log10(-0.15* (db) +1)
+ normalized = 1 - self.clamp(logscale, 0, 1)
+ return normalized
+
+ def clamp(self, value, min_value, max_value):
+ return max(min(value, max_value), min_value)
+
+ def level_callback(self, rms, peak, decay):
self.levelrms = rms
+ self.levelpeak = peak
+ self.leveldecay = decay
self.drawing_area.queue_draw()