1 /* Demo Recorder 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
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
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.
20 public class AudioCaptureMonitor : Gst.Pipeline {
21 //Gst.Pipeline pipeline;
23 //Gst.Element converter;
24 //Gst.Element pregain;
25 //Gst.Element dynamics;
30 Gst.Element sink_element;
33 public AudioCaptureMonitor(string name) {
35 construct_pipeline(SettingsStructures.MonitorSettings());
37 public AudioCaptureMonitor.with_settings(string name, SettingsStructures.MonitorSettings settings) {
39 construct_pipeline(settings);
42 private void construct_pipeline(SettingsStructures.MonitorSettings settings) {
44 this.src = Gst.ElementFactory.make("pulsesrc", "capture");
45 this.src.set_property("device", "source.hw0");
48 this.converter = Gst.ElementFactory.make("audioconvert", "converter");
49 this.add(this.converter);
51 this.pregain = Gst.ElementFactory.make("volume", "pregain");
52 this.pregain.set_property("volume", 1);
53 this.add(this.pregain);
55 this.dynamics = Gst.ElementFactory.make("audiodynamic", "dynamics");
56 this.add(this.dynamics);
57 this.dynamics.set_property("mode", "compressor"); // compressor or expander
58 this.dynamics.set_property("characteristics", "hard-knee"); // hard-knee or soft-knee
59 this.dynamics.set_property("threshold", 1.0); // [0, 1]
60 this.dynamics.set_property("ratio", 1.0); // >= 0
62 this.volume = Gst.ElementFactory.make("volume", "volume");
63 this.volume.set_property("volume", 1);
64 this.add(this.volume);
67 this.input = new InputBin.with_settings("input", settings.input);
70 this.level = Gst.ElementFactory.make("level", "level");
71 this.level.set_property("interval", 50 * Time.Nanoseconds.MILLISECOND);
72 this.level.set_property("peak-ttl", 2 * Time.Nanoseconds.SECOND);
75 this.monitor = Gst.ElementFactory.make("volume", "monitor");
76 this.monitor.set_property("volume", 1);
77 this.monitor.set_property("mute", true);
78 this.add(this.monitor);
80 this.sink_element = Gst.ElementFactory.make("autoaudiosink", "fakesink");
81 this.add(this.sink_element);
83 this.level.set_property("message", true);
85 this.sink_element.set_property("sync", true);
88 //Gst.Caps caps = Gst.Caps.from_string ("audio/x-raw-int,channels=2");
89 //this.converter.link_filtered(level, caps);
91 this.src.link(converter);
92 this.converter.link(pregain);
93 this.pregain.link(dynamics);
94 this.dynamics.link(volume);
95 this.volume.link(level);
97 this.input.link(level);
98 this.level.link(monitor);
99 this.monitor.link(sink_element);
101 Gst.Bus bus = this.get_bus();
103 watch_id = bus.add_watch(message_handler);
107 public void set_dynamics(string mode, string characteristics, double threshold, double ratio) {
108 this.input.set_dynamics(mode, characteristics, threshold, ratio);
110 this.dynamics.set_property("mode", mode); // compressor or expander
111 this.dynamics.set_property("characteristics", characteristics); // hard-knee or soft-knee
112 this.dynamics.set_property("threshold", threshold); // [0, 1]
113 this.dynamics.set_property("ratio", ratio); // >= 0
116 public void set_dynamics_mode(string mode) {
117 this.input.set_dynamics_mode(mode);
118 //this.dynamics.set_property("mode", mode); // compressor or expander
120 public void set_dynamics_characteristics(string characteristics) {
121 this.input.set_dynamics_characteristics(characteristics);
122 //this.dynamics.set_property("characteristics", characteristics); // hard-knee or soft-knee
124 public void set_dynamics_threshold(double threshold) {
125 this.input.set_dynamics_threshold(threshold);
126 //this.dynamics.set_property("threshold", threshold); // [0, 1]
128 public void set_dynamics_ratio(double ratio) {
129 this.input.set_dynamics_ratio(ratio);
130 //this.dynamics.set_property("ratio", ratio); // >= 0
133 public void set_source(string name) {
134 this.input.set_source(name);
136 public string get_source() {
137 return this.input.get_source();
140 public void set_pregain(double val)
141 requires (val >= 0.0 && val <= 10.0) {
142 this.input.set_pregain(val);
143 //this.pregain.set_property("volume", val);
145 public double get_pregain()
146 ensures (result >= 0.0 && result <= 10.0) {
147 return this.input.get_pregain();
148 /*GLib.Value val = 0;
149 this.pregain.get_property("volume", ref val);
150 return val.get_double();*/
153 public void set_volume(double val)
154 requires (val >= 0.0 && val <= 10.0) {
155 this.input.set_volume(val);
156 //this.volume.set_property("volume", val);
158 public double get_volume()
159 ensures (result >= 0.0 && result <= 10.0) {
160 return this.input.get_volume();
161 /*GLib.Value val = 0;
162 this.volume.get_property("volume", ref val);
163 return val.get_double();*/
166 public void set_mute(bool val) {
167 this.input.set_mute(val);
168 //this.volume.set_property("mute", val);
170 public bool get_mute() {
171 return this.input.get_mute();
172 /*GLib.Value val = 0;
173 this.volume.get_property("mute", ref val);
174 return val.get_boolean();*/
177 public void set_monitor_mute(bool val) {
178 this.monitor.set_property("mute", val);
180 public bool get_monitor_mute() {
182 this.monitor.get_property("mute", ref val);
183 return val.get_boolean();
187 this.set_state(Gst.State.PLAYING);
190 public void pause() {
191 this.set_state(Gst.State.READY);
195 this.set_state(Gst.State.READY);
198 public signal void update_level(int channels, int channel, double rms_dB, double peak_dB, double decay_dB, double rms);
200 public bool message_handler(Gst.Bus bus, Gst.Message message) {
201 if (Gst.MessageType.ELEMENT == message.type) {
202 Gst.Structure s = message.get_structure();
203 string name = s.get_name();
205 if ("level" == name) {
207 double rms_dB, peak_dB, decay_dB;
213 list = s.get_value("rms"); // any value gives us the channelsby list size
215 channels = (int) list.list_get_size();
217 for (i = 0; i < channels; ++i) {
218 list = s.get_value ("rms");
219 value = list.list_get_value (i);
220 rms_dB = value.get_double ();
221 list = s.get_value ("peak");
222 value = list.list_get_value (i);
223 peak_dB = value.get_double ();
224 list = s.get_value ("decay");
225 value = list.list_get_value (i);
226 decay_dB = value.get_double ();
227 /* converting from dB to normal gives us a value between 0.0 and 1.0 */
228 rms = Math.pow (10, rms_dB / 20);
229 update_level(channels, i, rms_dB, peak_dB, decay_dB, rms);