/* Demo Recorder for MAEMO 5 * Copyright (C) 2010 Dru Moore * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or (at your option) any later version, as published by the Free * Software Foundation * * This program 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 this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ namespace IdWorks { public class AudioCaptureMonitor : Gst.Pipeline { //Gst.Pipeline pipeline; //Gst.Element src; //Gst.Element converter; //Gst.Element pregain; //Gst.Element dynamics; //Gst.Element volume; InputBin input; Gst.Element level; Gst.Element monitor; Gst.Element sink_element; uint watch_id; public AudioCaptureMonitor(string name) { this.name = name; construct_pipeline(SettingsStructures.MonitorSettings()); } public AudioCaptureMonitor.with_settings(string name, SettingsStructures.MonitorSettings settings) { this.name = name; construct_pipeline(settings); } private void construct_pipeline(SettingsStructures.MonitorSettings settings) { /* this.src = Gst.ElementFactory.make("pulsesrc", "capture"); this.src.set_property("device", "source.hw0"); this.add(this.src); this.converter = Gst.ElementFactory.make("audioconvert", "converter"); this.add(this.converter); this.pregain = Gst.ElementFactory.make("volume", "pregain"); this.pregain.set_property("volume", 1); this.add(this.pregain); this.dynamics = Gst.ElementFactory.make("audiodynamic", "dynamics"); this.add(this.dynamics); this.dynamics.set_property("mode", "compressor"); // compressor or expander this.dynamics.set_property("characteristics", "hard-knee"); // hard-knee or soft-knee this.dynamics.set_property("threshold", 1.0); // [0, 1] this.dynamics.set_property("ratio", 1.0); // >= 0 this.volume = Gst.ElementFactory.make("volume", "volume"); this.volume.set_property("volume", 1); this.add(this.volume); */ this.input = new InputBin.with_settings("input", settings.input); this.add(this.input); this.level = Gst.ElementFactory.make("level", "level"); this.level.set_property("interval", 50 * Time.Nanoseconds.MILLISECOND); this.level.set_property("peak-ttl", 2 * Time.Nanoseconds.SECOND); this.add(this.level); this.monitor = Gst.ElementFactory.make("volume", "monitor"); this.monitor.set_property("volume", 1); this.monitor.set_property("mute", true); this.add(this.monitor); this.sink_element = Gst.ElementFactory.make("autoaudiosink", "fakesink"); this.add(this.sink_element); this.level.set_property("message", true); this.sink_element.set_property("sync", true); //Gst.Caps caps = Gst.Caps.from_string ("audio/x-raw-int,channels=2"); //this.converter.link_filtered(level, caps); /* this.src.link(converter); this.converter.link(pregain); this.pregain.link(dynamics); this.dynamics.link(volume); this.volume.link(level); */ this.input.link(level); this.level.link(monitor); this.monitor.link(sink_element); Gst.Bus bus = this.get_bus(); watch_id = bus.add_watch(message_handler); } public void set_dynamics(string mode, string characteristics, double threshold, double ratio) { this.input.set_dynamics(mode, characteristics, threshold, ratio); /* this.dynamics.set_property("mode", mode); // compressor or expander this.dynamics.set_property("characteristics", characteristics); // hard-knee or soft-knee this.dynamics.set_property("threshold", threshold); // [0, 1] this.dynamics.set_property("ratio", ratio); // >= 0 */ } public void set_dynamics_mode(string mode) { this.input.set_dynamics_mode(mode); //this.dynamics.set_property("mode", mode); // compressor or expander } public void set_dynamics_characteristics(string characteristics) { this.input.set_dynamics_characteristics(characteristics); //this.dynamics.set_property("characteristics", characteristics); // hard-knee or soft-knee } public void set_dynamics_threshold(double threshold) { this.input.set_dynamics_threshold(threshold); //this.dynamics.set_property("threshold", threshold); // [0, 1] } public void set_dynamics_ratio(double ratio) { this.input.set_dynamics_ratio(ratio); //this.dynamics.set_property("ratio", ratio); // >= 0 } public void set_source(string name) { this.input.set_source(name); } public string get_source() { return this.input.get_source(); } public void set_pregain(double val) requires (val >= 0.0 && val <= 10.0) { this.input.set_pregain(val); //this.pregain.set_property("volume", val); } public double get_pregain() ensures (result >= 0.0 && result <= 10.0) { return this.input.get_pregain(); /*GLib.Value val = 0; this.pregain.get_property("volume", ref val); return val.get_double();*/ } public void set_volume(double val) requires (val >= 0.0 && val <= 10.0) { this.input.set_volume(val); //this.volume.set_property("volume", val); } public double get_volume() ensures (result >= 0.0 && result <= 10.0) { return this.input.get_volume(); /*GLib.Value val = 0; this.volume.get_property("volume", ref val); return val.get_double();*/ } public void set_mute(bool val) { this.input.set_mute(val); //this.volume.set_property("mute", val); } public bool get_mute() { return this.input.get_mute(); /*GLib.Value val = 0; this.volume.get_property("mute", ref val); return val.get_boolean();*/ } public void set_monitor_mute(bool val) { this.monitor.set_property("mute", val); } public bool get_monitor_mute() { GLib.Value val = 0; this.monitor.get_property("mute", ref val); return val.get_boolean(); } public void play() { this.set_state(Gst.State.PLAYING); } public void pause() { this.set_state(Gst.State.READY); } public void stop() { this.set_state(Gst.State.READY); } public signal void update_level(int channels, int channel, double rms_dB, double peak_dB, double decay_dB, double rms); public bool message_handler(Gst.Bus bus, Gst.Message message) { if (Gst.MessageType.ELEMENT == message.type) { Gst.Structure s = message.get_structure(); string name = s.get_name(); if ("level" == name) { int channels; double rms_dB, peak_dB, decay_dB; double rms; Gst.Value list; Gst.Value value; int i; list = s.get_value("rms"); // any value gives us the channelsby list size channels = 0; channels = (int) list.list_get_size(); for (i = 0; i < channels; ++i) { list = s.get_value ("rms"); value = list.list_get_value (i); rms_dB = value.get_double (); list = s.get_value ("peak"); value = list.list_get_value (i); peak_dB = value.get_double (); list = s.get_value ("decay"); value = list.list_get_value (i); decay_dB = value.get_double (); /* converting from dB to normal gives us a value between 0.0 and 1.0 */ rms = Math.pow (10, rms_dB / 20); update_level(channels, i, rms_dB, peak_dB, decay_dB, rms); } } } return true; } } }