Skip to content

Commit

Permalink
Merge pull request #222 from sophieschi/audioleveldisplay
Browse files Browse the repository at this point in the history
VU meters for all audiostreams
  • Loading branch information
sophieschi authored Nov 5, 2018
2 parents d0fabf6 + 389447b commit 7d182b2
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 30 deletions.
2 changes: 2 additions & 0 deletions voctogui/default-config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use=true
[mainvideo]
# disabled by default because it seems there's an issue, see
# https://github.com/voc/voctomix/issues/37
# number of vu meters to display, set vumeter=all to to show VU meters of all audiostreams in gui
vumeter=1
playaudio=false

[videodisplay]
Expand Down
34 changes: 23 additions & 11 deletions voctogui/lib/audioleveldisplay.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
import math
import cairo

from gi.repository import Gtk, GLib
from lib.config import Config
from gi.repository import Gtk, GLib, Gst


class AudioLevelDisplay(Gtk.DrawingArea):
"""Displays a Level-Meter of another VideoDisplay into a GtkWidget"""
__gtype_name__ = 'AudioLevelDisplay'

def __init__(self):
self.levelrms = []
self.levelpeak = []
self.leveldecay = []
self.num_audiostreams_ = int(Config.get('mix', 'audiostreams'))
meters = Config.get('mainvideo', 'vumeter')
if (meters != 'all') and (int(meters) < self.num_audiostreams_):
self.num_audiostreams_ = int(meters)

self.channels = 2
acaps = Gst.Caps.from_string(Config.get('mix', 'audiocaps'))
self.channels = int(acaps.get_structure(0).get_int("channels")[1])

self.levelrms = [0] * self.channels * self.num_audiostreams_
self.levelpeak = [0] * self.channels * self.num_audiostreams_
self.leveldecay = [0] * self.channels * self.num_audiostreams_

self.height = -1

self.set_size_request(20 * self.num_audiostreams_, -1)

# register on_draw handler
self.connect('draw', self.draw_callback)

Expand Down Expand Up @@ -129,10 +141,10 @@ def normalize_db(self, db):
def clamp(self, value, min_value=0, max_value=1):
return max(min(value, max_value), min_value)

def level_callback(self, rms, peak, decay):
if self.levelrms != rms or self.levelpeak != peak \
or self.leveldecay != decay:
self.levelrms = rms
self.levelpeak = peak
self.leveldecay = decay
self.queue_draw()
def level_callback(self, rms, peak, decay, stream):
meter_offset = self.channels * stream
for i in range(0, self.channels):
self.levelrms[meter_offset + i] = rms[i]
self.levelpeak[meter_offset + i] = peak[i]
self.leveldecay[meter_offset + i] = decay[i]
self.queue_draw()
49 changes: 31 additions & 18 deletions voctogui/lib/videodisplay.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import re
from gi.repository import Gst

from lib.args import Args
Expand All @@ -24,6 +25,12 @@ def __init__(self, drawing_area, port, width=None, height=None,
use_previews = Config.getboolean('previews', 'enabled') \
and Config.getboolean('previews', 'use')

audiostreams = int(Config.get('mix', 'audiostreams'))

if (Config.get('mainvideo', 'vumeter') != 'all') \
and int(Config.get('mainvideo', 'vumeter')) < audiostreams:
audiostreams = int(Config.get('mainvideo', 'vumeter'))

# Preview-Ports are Raw-Ports + 1000
if use_previews:
self.log.info('using encoded previews instead of raw-video')
Expand Down Expand Up @@ -103,24 +110,29 @@ def __init__(self, drawing_area, port, width=None, height=None,
# If an Audio-Path is required,
# add an Audio-Path through a level-Element
if self.level_callback or play_audio:
pipeline += """
demux. !
{acaps} !
queue !
level name=lvl interval=50000000 !
"""

# If Playback is requested, push fo pulseaudio
if play_audio:
for audiostream in range(0, audiostreams):
pipeline += """
pulsesink
"""

# Otherwise just trash the Audio
else:
demux.audio_{audiostream} !
""".format(audiostream=audiostream)
pipeline += """
{acaps} !
queue !
"""
pipeline += """
fakesink
"""
level name=lvl_{audiostream} interval=50000000 !
""".format(audiostream=audiostream)

# If Playback is requested, push fo pulseaudio
if play_audio and audiostream == 0:
pipeline += """
pulsesink
"""

# Otherwise just trash the Audio
else:
pipeline += """
fakesink
"""

pipeline = pipeline.format(
acaps=Config.get('mix', 'audiocaps'),
Expand Down Expand Up @@ -163,7 +175,7 @@ def on_error(self, bus, message):
self.log.debug('Error-Details: #%u: %s', error.code, debug)

def on_level(self, bus, msg):
if msg.src.name != 'lvl':
if not(msg.src.name.startswith('lvl_')):
return

if msg.type != Gst.MessageType.ELEMENT:
Expand All @@ -172,4 +184,5 @@ def on_level(self, bus, msg):
rms = msg.get_structure().get_value('rms')
peak = msg.get_structure().get_value('peak')
decay = msg.get_structure().get_value('decay')
self.level_callback(rms, peak, decay)
stream = int(msg.src.name[4])
self.level_callback(rms, peak, decay, stream)
1 change: 0 additions & 1 deletion voctogui/ui/voctogui.ui
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@
</child>
<child>
<object class="AudioLevelDisplay" id="audiolevel_main">
<property name="width_request">30</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_right">5</property>
Expand Down

0 comments on commit 7d182b2

Please sign in to comment.