/* 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 AcmPopUp : Hildon.Dialog { SettingsStructures.MonitorSettings settings; AudioCaptureMonitor acm; Gtk.Label lbl_level_1; Gtk.Label lbl_level_2; Gtk.HScale pregain_slider; Gtk.HScale volume_slider; Hildon.Button dynamics_settings_btn; Hildon.CheckButton dynamics_btn; Hildon.TouchSelector source_selector; DbMonitorWidget monitor_1; DbMonitorWidget monitor_2; const string level_format = "%02.1f/%02.1fdB"; public AcmPopUp(string title, Gtk.Widget parent) { this.set_title(title); this.set_parent(parent); this.settings = SettingsStructures.MonitorSettings(); this.construct_interface(); update_settings(); } public AcmPopUp.with_settings(string title, Gtk.Widget parent, SettingsStructures.MonitorSettings settings) { this.set_title(title); this.set_parent(parent); this.settings = settings; this.construct_interface(); update_settings(); } public void set_settings_structure(SettingsStructures.MonitorSettings settings) { this.settings = settings; update_settings(); } public SettingsStructures.MonitorSettings get_settings_structure() { return this.settings; } private void update_settings() { set_volume(settings.input.volume); set_pregain(settings.input.pregain); //set_source(settings.input.source); dynamics_btn.set_active(settings.input.dynamics.active); toggle_dynamics(settings.input.dynamics.active); } private void set_volume(double val) { volume_slider.set_value(val); settings.input.volume = val; if (null != acm) acm.set_volume(val); } private void set_pregain(double val) { pregain_slider.set_value(val); settings.input.pregain = val; if (null != acm) acm.set_pregain(val); } private void set_source(string name) { switch (name) { case "Microphone": source_selector.set_active(0, 0); break; case "Monitor": source_selector.set_active(0, 1); break; case "Bluetooth": source_selector.set_active(0, 2); break; default: source_selector.set_active(0, 0); break; } settings.input.source = name; if (null != acm) acm.set_source(name); } private void set_input_source(string name) { settings.input.source = name; if (null != acm) acm.set_source(name); } private void construct_interface() { this.set_default_response(Gtk.ResponseType.CANCEL); this.add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK); this.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL); Gtk.VBox control_area = (Gtk.VBox)this.get_content_area(); acm = new AudioCaptureMonitor("Recorder"); acm.update_level.connect(update_level_callback); Gtk.HButtonBox input_bar = new Gtk.HButtonBox(); input_bar.set_layout(Gtk.ButtonBoxStyle.START); input_bar.set_homogeneous(true); input_bar.set_spacing(2); source_selector = new Hildon.TouchSelector.text(); source_selector.append_text("Microphone"); source_selector.append_text("Monitor"); source_selector.append_text("Bluetooth"); //source_selector.set_active(0, 0); this.set_source(settings.input.source); Hildon.PickerButton source_picker = new Hildon.PickerButton(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH, Hildon.ButtonArrangement.VERTICAL); source_picker.set_title("Source:"); source_picker.set_selector(source_selector); source_picker.set_alignment(0, 0, 1, 1); source_picker.set_image(new Gtk.Image.from_icon_name("camera_volume_unmuted", Gtk.IconSize.BUTTON)); source_picker.value_changed.connect( (s) => { set_input_source(s.get_selector().get_current_text()); } ); input_bar.pack_start(source_picker, true, true, 2); Hildon.CheckButton audio_btn = new Hildon.CheckButton(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH); audio_btn.set_label("Enable monitor"); //audio_btn.set_image(new Gtk.Image.from_icon_name("statusarea_volume_headset", Gtk.IconSize.BUTTON)); audio_btn.toggled.connect( (s) => {toggle_monitor(s.get_active());} ); input_bar.pack_start(audio_btn, true, false, 2); control_area.pack_start(input_bar, true, true, 4); Gtk.HBox monitor_1_bar = new Gtk.HBox(false, 2); lbl_level_1 = new Gtk.Label(level_format.printf(0, 0)); monitor_1 = new DbMonitorWidget(); monitor_1.set_layout(DbMonitorWidget.Layout.HORIZONTAL); monitor_1.set_peak(1); monitor_1.set_decay(1.5); monitor_1_bar.pack_start(new Gtk.Label("L"), false, false, 2); monitor_1_bar.pack_start(monitor_1, true, true, 2); monitor_1_bar.pack_start(lbl_level_1, false, false, 2); control_area.pack_start(monitor_1_bar, true, true, 2); Gtk.HBox monitor_2_bar = new Gtk.HBox(false, 4); lbl_level_2 = new Gtk.Label(level_format.printf(0, 0)); monitor_2 = new DbMonitorWidget(); monitor_2.set_layout(DbMonitorWidget.Layout.HORIZONTAL); monitor_2.set_peak(1); monitor_2.set_decay(1.5); monitor_2_bar.pack_start(new Gtk.Label("R"), false, false, 2); monitor_2_bar.pack_start(monitor_2, true, true, 2); monitor_2_bar.pack_start(lbl_level_2, false, false, 2); control_area.pack_start(monitor_2_bar, true, true, 2); Gtk.HBox pregain_bar = new Gtk.HBox(false, 4); Gtk.Label pregain_label = new Gtk.Label("Pre-gain"); pregain_bar.pack_start(pregain_label, false, false , 2); pregain_slider = new Gtk.HScale.with_range(0.0, 10.0, 0.1); pregain_slider.set_value_pos(Gtk.PositionType.LEFT); pregain_slider.value_changed.connect((s) => {this.set_pregain(s.get_value());}); pregain_bar.pack_start(pregain_slider, true, true , 2); control_area.pack_start(pregain_bar, true, true , 2); Gtk.HBox dynamics_bar = new Gtk.HBox(false, 4); dynamics_btn = new Hildon.CheckButton(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH); dynamics_btn.set_label("Enable dynamics"); dynamics_btn.toggled.connect( (s) => {toggle_dynamics(s.get_active());} ); dynamics_bar.pack_start(dynamics_btn, true, false, 2); dynamics_settings_btn = new Hildon.Button(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH, Hildon.ButtonArrangement.HORIZONTAL); dynamics_settings_btn.set_text("Settings", ""); dynamics_settings_btn.set_image(new Gtk.Image.from_icon_name("general_settings", Gtk.IconSize.BUTTON)); dynamics_settings_btn.set_image_position(Gtk.PositionType.LEFT); dynamics_settings_btn.clicked.connect(do_dynamics_popup); dynamics_bar.pack_start(dynamics_settings_btn, true, false, 2); control_area.pack_start(dynamics_bar, true, true , 2); Gtk.HBox volume_bar = new Gtk.HBox(false, 4); Gtk.Label volume_label = new Gtk.Label("Volume"); volume_bar.pack_start(volume_label, false, false , 2); volume_slider = new Gtk.HScale.with_range(0.0, 10.0, 0.1); volume_slider.set_value_pos(Gtk.PositionType.LEFT); volume_slider.value_changed.connect((s) => {this.set_volume(s.get_value());}); volume_bar.pack_start(volume_slider, true, true , 2); control_area.pack_start(volume_bar, true, true , 2); this.update_settings(); this.show_all(); } public void play() { acm.play(); } public void pause() { acm.pause(); } public void stop() { acm.stop(); } private void toggle_monitor(bool state) { if (null != acm) { acm.set_monitor_mute(!state); } } private void toggle_dynamics(bool state) { this.settings.input.dynamics.active = state; this.dynamics_settings_btn.set_sensitive(state); if (null != acm) { if (!state) { SettingsStructures.DynamicsSettings ds = SettingsStructures.DynamicsSettings(); acm.set_dynamics(ds.mode, ds.characteristics, ds.threshold, ds.ratio); // shouldn't be applied } else { acm.set_dynamics(settings.input.dynamics.mode, settings.input.dynamics.characteristics, settings.input.dynamics.threshold, settings.input.dynamics.ratio); } } } private void do_dynamics_popup() { stdout.printf("dynamics popup new called\n"); stdout.flush(); DynamicsPopUp dlg = new DynamicsPopUp.with_settings("Monitoring dynamics settings", this, settings.input.dynamics); dlg.set_transient_for(this.get_transient_for()); dlg.mode_updated.connect(this.dynamics_update_mode_callback); dlg.characteristics_updated.connect(this.dynamics_update_characteristics_callback); dlg.ratio_updated.connect(this.dynamics_update_ratio_callback); dlg.threshold_updated.connect(this.dynamics_update_threshold_callback); stdout.printf("dynamics connections made\n"); stdout.flush(); dlg.run(); stdout.printf("dynamics back from run\n"); stdout.flush(); dlg.destroy(); } private void dynamics_update_mode_callback(DynamicsPopUp sender, string val) { settings.input.dynamics.mode = val; if (null != acm) { acm.set_dynamics_mode(val); } } private void dynamics_update_characteristics_callback(DynamicsPopUp sender, string val) { settings.input.dynamics.characteristics = val; if (null != acm) { acm.set_dynamics_characteristics(val); } } private void dynamics_update_ratio_callback(DynamicsPopUp sender, double val) { settings.input.dynamics.ratio = val; if (null != acm) { acm.set_dynamics_ratio(val); } } private void dynamics_update_threshold_callback(DynamicsPopUp sender, double val) { settings.input.dynamics.threshold = val; if (null != acm) { acm.set_dynamics_threshold(val); } } private void update_level_callback(AudioCaptureMonitor sender, int channels, int channel, double rms_dB, double peak_dB, double decay_dB, double rms) { //string text = level_format.printf(channel.to_string(), rms_dB, peak_dB, decay_dB, rms, Math.pow (10, decay_dB / 20)); string text = level_format.printf(peak_dB, decay_dB); if (0 == channel) { lbl_level_1.set_text(text); monitor_1.set_peak(Math.pow (10, peak_dB / 20)); monitor_1.set_decay(Math.pow (10, decay_dB / 20)); } else if (1 == channel) { lbl_level_2.set_text(text); monitor_2.set_peak(Math.pow (10, peak_dB / 20)); monitor_2.set_decay(Math.pow (10, decay_dB / 20)); } else { stdout.printf("channel %s found\n", channel.to_string()); stdout.flush(); } } } }