This file is indexed.

/usr/share/flowblade/Flowblade/audiomonitoring.py is in flowblade 0.8.0-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
"""
    Flowblade Movie Editor is a nonlinear video editor.
    Copyright 2012 Janne Liljeblad.

    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.

    Flowblade Movie Editor is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Flowblade Movie Editor is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
"""
import cairo
import gtk
import mlt

import sys

from cairoarea import CairoDrawableArea
import utils

CHANNEL_METERS_AREA_HEIGHT = 300 
CHANNEL_METERS_AREA_WIDTH = 300

METER_HEIGHT = 290
METER_WIDTH = 10

DASH_INK = 6.0
DASH_SKIP = 2.0
DASHES = [DASH_INK, DASH_SKIP, DASH_INK, DASH_SKIP]

# These are calculated using IEC_Scale function in MLT
DB_IEC_MINUS_2 = 0.95
DB_IEC_MINUS_4 = 0.9
DB_IEC_MINUS_6 = 0.85
DB_IEC_MINUS_10 = 0.75

PEAK_FRAMES = 5

RED_1 = (0, 1, 0, 0, 1)
RED_2 = (1 - DB_IEC_MINUS_2, 1, 0, 0, 1)
YELLOW_1 = (1 - DB_IEC_MINUS_2 + 0.001, 1, 1, 0, 1)
YELLOW_2 = (1 - DB_IEC_MINUS_6, 1, 1, 0, 1)
GREEN_1 = (1 - DB_IEC_MINUS_6 + 0.001, 0, 1, 0, 1)
GREEN_2 = (1, 0, 1, 0, 1)
        

MONITORING_AVAILABLE = False

_monitor_window = None
_update_ticker = None
_producer = None
 
def init():
    audio_level_filter = mlt.Filter(self.profile, "audiolevel")
    print DB_IEC_MINUS_2, DB_IEC_MINUS_6

    global MONITORING_AVAILABLE
    if audio_level_filter != None:
        MONITORING_AVAILABLE = True
    else:
        MONITORING_AVAILABLE = False
    
def add_audio_level_filter(producer, profile):
    audio_level_filter = mlt.Filter(profile, "audiolevel")
    producer.attach(audio_level_filter)
    producer.audio_level_filter = audio_level_filter
    global _producer
    _producer = producer
    
def remove_audio_level_filter(producer, profile):
    producer.detach(producer.audio_level_filter)
    producer.audio_level_filter = None

def start_monitoring():
    red = DB_IEC_MINUS_4
    yellow = DB_IEC_MINUS_10

    global _monitor_window
    _monitor_window = AudioMonitorWindow()
        
    global _update_ticker
    _update_ticker = utils.Ticker(_audio_monitor_update, 0.04)
    _update_ticker.start_ticker()

def _audio_monitor_update():
    level_value = _producer.audio_level_filter.get("_audio_level.1")
    if level_value == None:
        level_value  = "0.0"

    try:
        level_float = float(level_value)
    except Exception, err:
        print err
        level_float = 0.0

    _monitor_window.channel_meters.channel_values[0] = (level_float, level_float)
    _monitor_window.channel_meters.widget.queue_draw()

    """
    level_steps = int(level_float * 20)
    level_str = ''.join(["#" for num in xrange(level_steps)])
    #print level_str
    sys.stdout.write("\r\x1b[K"+level_str.__str__())
    sys.stdout.flush()
    """
    
class AudioMonitorWindow(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self)

        self.channel_meters = ChannelMetersArea(1)

        pane = gtk.VBox(False, 1)
        pane.pack_start(self.channel_meters.widget, True, True, 0)
        
        # Set pane and show window
        self.add(pane)
        self.show_all()

class ChannelMetersArea:
    def __init__(self, channels_count):    
        self.widget = CairoDrawableArea(CHANNEL_METERS_AREA_HEIGHT,
                                        CHANNEL_METERS_AREA_WIDTH, 
                                        self._draw)
        self.channels_count = channels_count
        
        self.channel_values = [] # (l_value, r_value) tuples
        self.channel_meters = [] # displays both l_Value and r_value
        for i in range(0, self.channels_count):
            self.channel_values.append((0.0, 0.0))
            self.channel_meters.append(AudioMeter(METER_HEIGHT))
            
    def _draw(self, event, cr, allocation):
        x, y, w, h = allocation

        cr.set_source_rgb(0,0,0)
        cr.rectangle(0, 0, w, h)
        cr.fill()

        grad = cairo.LinearGradient (0, 0, 0, h)
        grad.add_color_stop_rgba(*RED_1)
        grad.add_color_stop_rgba(*RED_2)
        grad.add_color_stop_rgba(*YELLOW_1)
        grad.add_color_stop_rgba(*YELLOW_2)
        grad.add_color_stop_rgba(*GREEN_1)
        grad.add_color_stop_rgba(*GREEN_2)
        cr.set_source(grad)

        cr.set_dash(DASHES, 0) 
        cr.set_line_width(METER_WIDTH)
        
        for i in range(0, self.channels_count):
            meter = self.channel_meters[i]
            l_value, r_value = self.channel_values[i]
            meter.display_value(cr, 25, l_value)

class AudioMeter:
    def __init__(self, height):
        self.height = height
        self.peak = 0.0
        self.countdown = 0

    def display_value(self, cr, x, value):
        top = self.get_meter_y_for_value(value)
        
        cr.move_to(x, self.height)
        cr.line_to(x, top)
        cr.stroke()
        
        if value > self.peak:
            self.peak = value
            self.countdown = PEAK_FRAMES
        
        if self.peak > value:
            cr.rectangle(x - METER_WIDTH / 2, 
                         self.get_meter_y_for_value(self.peak) + DASH_SKIP,
                         METER_WIDTH,
                         DASH_INK)
            cr.fill()

        self.countdown = self.countdown - 1
        if self.countdown <= 0:
             self.peak = 0

    def get_meter_y_for_value(self, value):
        y = self.height -  (value * self.height)
        dash_sharp_pad = (self.height - y) % (DASH_INK + DASH_SKIP)
        return y + dash_sharp_pad