1 /* Copyright 2009-2010 Yorba Foundation
3 * This software is licensed under the GNU Lesser General Public License
4 * (version 2.1 or later). See the COPYING file in this distribution.
10 public class AudioMeter : Gtk.DrawingArea {
11 Cairo.ImageSurface meter = null;
12 Cairo.ImageSurface silkscreen;
15 double current_level_left = -100;
16 double current_level_right = -100;
17 const double minDB = -70;
19 public AudioMeter(Model.AudioTrack track) {
20 int number_of_channels;
21 if (track.get_num_channels(out number_of_channels)) {
22 stereo = number_of_channels < 1;
25 this.requisition.height = 10;
26 expose_event.connect(on_expose_event);
27 track.level_changed.connect(on_level_changed);
28 track.channel_count_changed.connect(on_channel_count_changed);
31 void initialize_meter() {
32 meter = new Cairo.ImageSurface(Cairo.Format.ARGB32,
33 allocation.width, allocation.height);
34 Cairo.Context context2 = new Cairo.Context(meter);
35 Cairo.Pattern pat = new Cairo.Pattern.linear(0, 0, allocation.width, 0);
36 pat.add_color_stop_rgb(0, 0.1, 1, 0.4);
37 pat.add_color_stop_rgb(0.8, 1, 1, 0);
38 pat.add_color_stop_rgb(1, 1, 0, 0);
39 context2.set_source(pat);
40 context2.rectangle(0, 0, allocation.width, allocation.height);
43 silkscreen = new Cairo.ImageSurface(Cairo.Format.ARGB32,
44 allocation.width, allocation.height);
45 context2 = new Cairo.Context(silkscreen);
46 context2.set_source_rgba(0, 0, 0, 0);
47 context2.rectangle(0, 0, allocation.width, allocation.height);
50 // draw the segment edges
51 for (int i=0;i<20;++i) {
52 context2.set_source_rgba(0, 0, 0, 1);
53 context2.rectangle(i * allocation.width / 20, 0, 3, allocation.height);
57 // draw a bevel around the edge
58 context2.set_line_width(1.1);
59 context2.set_source_rgba(0.9, 0.9, 0.9, 0.5);
60 context2.rectangle(0, 0, allocation.width, allocation.height);
64 public bool on_expose_event(Gdk.EventExpose event) {
65 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_expose_event");
66 Gdk.Window window = get_window();
67 Cairo.Context context = Gdk.cairo_create(window);
72 context.set_source_rgb(0, 0, 0);
73 context.rectangle(0, 0, allocation.width, allocation.height);
76 int bar_height = stereo ? (allocation.height / 2) - 1 : allocation.height - 2;
79 context.set_source_rgb(1, 1, 1);
80 context.rectangle(0, bar_height + 1, allocation.width, 0.3);
84 context.set_source_surface(meter, 0, 0);
85 int width = (int) (Math.pow10(current_level_left / 40) * allocation.width);
86 context.rectangle(0, 1, width, bar_height);
89 width = (int) (Math.pow10(current_level_right / 40) * allocation.width);
90 context.rectangle(0, bar_height + 2, width, bar_height);
94 context.paint_with_alpha(1);
96 context.set_source_surface(silkscreen, 0, 0);
97 context.paint_with_alpha(1);
102 public void on_level_changed(double level_left, double level_right) {
103 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_level_changed");
104 current_level_left = level_left < minDB ? minDB : level_left;
105 current_level_right = level_right < minDB ? minDB : level_right;
106 Gdk.Window window = get_window();
107 window.invalidate_rect(null, false);
110 public void on_channel_count_changed(int number_of_channels) {
111 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_channel_count_changed");
112 stereo = number_of_channels > 1;
113 window.invalidate_rect(null, false);