Initial project commit
[decibelmeter] / src / AudioCaptureMonitor.vala
1 /*  Decibel Meter for MAEMO 5
2 *   Copyright (C) 2010 Dru Moore <usr@dru-id.co.uk>
3 *   This program is free software; you can redistribute it and/or modify
4 *   it under the terms of the GNU General Public License version 2,
5 *   or (at your option) any later version, as published by the Free
6 *   Software Foundation
7 *
8 *   This program is distributed in the hope that it will be useful,
9 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *   GNU General Public License for more details
12 *
13 *   You should have received a copy of the GNU General Public
14 *   License along with this program; if not, write to the
15 *   Free Software Foundation, Inc.,
16 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 */
18 namespace IdWorks {
19
20 public class AudioCaptureMonitor : Gst.Pipeline {
21   InputBin input;
22   Gst.Element level;
23   Gst.Element monitor;
24   Gst.Element sink_element;
25   uint watch_id;
26   
27   public AudioCaptureMonitor(string name) {
28     this.name = name;
29     construct_pipeline("Microphone", 1.0);
30   }
31   public AudioCaptureMonitor.with_settings(string name, string source, double volume) {
32     this.name = name;
33     construct_pipeline(source, volume);
34   }
35   
36   private void construct_pipeline(string source, double volume) {
37     
38     this.input = new InputBin.with_settings("input", source, 1.0);
39     this.add(this.input);
40     
41     this.level = Gst.ElementFactory.make("level", "level");
42     this.level.set_property("interval", 50 * Time.Nanoseconds.MILLISECOND);
43     this.level.set_property("peak-ttl", 2 * Time.Nanoseconds.SECOND);
44     this.add(this.level);
45     
46     this.monitor = Gst.ElementFactory.make("volume", "monitor");
47     this.monitor.set_property("volume", 1);
48     this.monitor.set_property("mute", true);
49     this.add(this.monitor);
50     
51     this.sink_element = Gst.ElementFactory.make("autoaudiosink", "fakesink");
52     this.add(this.sink_element);
53     
54     this.level.set_property("message", true);
55     
56     this.sink_element.set_property("sync", true);
57     
58     this.input.link(level);
59     this.level.link(monitor);
60     this.monitor.link(sink_element);
61     
62     Gst.Bus bus = this.get_bus();
63     
64     watch_id = bus.add_watch(message_handler);
65     
66   }
67   
68   
69   public void set_source(string name) {
70     this.input.set_source(name);
71   }
72   public string get_source() {
73     return this.input.get_source();
74   }
75   
76   public void set_volume(double val)
77   requires (val >= 0.0 && val <= 10.0) {
78     this.input.set_volume(val);
79     //this.volume.set_property("volume", val);
80   }
81   public double get_volume()
82   ensures (result >= 0.0 && result <= 10.0) {
83     return this.input.get_volume();
84     /*GLib.Value val = 0;
85     this.volume.get_property("volume", ref val);
86     return val.get_double();*/
87   }
88   
89   public void set_mute(bool val) {
90     this.input.set_mute(val);
91     //this.volume.set_property("mute", val);
92   }
93   public bool get_mute() {
94     return this.input.get_mute();
95     /*GLib.Value val = 0;
96     this.volume.get_property("mute", ref val);
97     return val.get_boolean();*/
98   }
99   
100   public void set_monitor_mute(bool val) {
101     this.monitor.set_property("mute", val);
102   }
103   public bool get_monitor_mute() {
104     GLib.Value val = 0;
105     this.monitor.get_property("mute", ref val);
106     return val.get_boolean();
107   }
108   
109   public void play() {
110     this.set_state(Gst.State.PLAYING);
111   }
112   
113   public void pause() {
114     this.set_state(Gst.State.READY);
115   }
116   
117   public void stop() {
118     this.set_state(Gst.State.READY);
119   }
120   
121   public signal void update_level(int channels, int channel, double rms_dB, double peak_dB, double decay_dB, double rms);
122   
123   public bool message_handler(Gst.Bus bus, Gst.Message message) {
124     if (Gst.MessageType.ELEMENT == message.type) {
125       Gst.Structure s = message.get_structure();
126       string name = s.get_name();
127       
128       if ("level" == name) {
129         int channels;
130         double rms_dB, peak_dB, decay_dB;
131         double rms;
132         Gst.Value list;
133         Gst.Value value;
134         int i;
135               
136         list = s.get_value("rms"); // any value gives us the channelsby list size
137         channels = 0;
138         channels = (int) list.list_get_size();
139         
140         for (i = 0; i < channels; ++i) {          
141           list = s.get_value ("rms");
142           value = list.list_get_value (i);
143           rms_dB = value.get_double ();
144           list = s.get_value ("peak");
145           value = list.list_get_value (i);
146           peak_dB = value.get_double ();
147           list = s.get_value ("decay");
148           value = list.list_get_value (i);
149           decay_dB = value.get_double ();
150           /* converting from dB to normal gives us a value between 0.0 and 1.0 */
151           rms = Math.pow (10, rms_dB / 20);
152           update_level(channels, i, rms_dB, peak_dB, decay_dB, rms);
153         }
154       }
155     }
156     return true;
157   }
158
159 }
160
161 }