Adding first code drop
[demorecorder] / src / AcmPopUp.vala
diff --git a/src/AcmPopUp.vala b/src/AcmPopUp.vala
new file mode 100644 (file)
index 0000000..1a618f0
--- /dev/null
@@ -0,0 +1,291 @@
+/*  Demo Recorder for MAEMO 5
+*   Copyright (C) 2010 Dru Moore <usr@dru-id.co.uk>
+*   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();
+      }
+    }
+    
+  }
+  
+}
\ No newline at end of file