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 AcmPopUp : Hildon.Dialog {
22 SettingsStructures.MonitorSettings settings;
23 AudioCaptureMonitor acm;
24 Gtk.Label lbl_level_1;
25 Gtk.Label lbl_level_2;
26 Gtk.HScale pregain_slider;
27 Gtk.HScale volume_slider;
28 Hildon.Button dynamics_settings_btn;
29 Hildon.CheckButton dynamics_btn;
30 Hildon.TouchSelector source_selector;
31 DbMonitorWidget monitor_1;
32 DbMonitorWidget monitor_2;
33 const string level_format = "%02.1f/%02.1fdB";
35 public AcmPopUp(string title, Gtk.Widget parent) {
36 this.set_title(title);
37 this.set_parent(parent);
38 this.settings = SettingsStructures.MonitorSettings();
39 this.construct_interface();
42 public AcmPopUp.with_settings(string title, Gtk.Widget parent, SettingsStructures.MonitorSettings settings) {
43 this.set_title(title);
44 this.set_parent(parent);
45 this.settings = settings;
46 this.construct_interface();
50 public void set_settings_structure(SettingsStructures.MonitorSettings settings) {
51 this.settings = settings;
54 public SettingsStructures.MonitorSettings get_settings_structure() {
58 private void update_settings() {
59 set_volume(settings.input.volume);
60 set_pregain(settings.input.pregain);
61 //set_source(settings.input.source);
62 dynamics_btn.set_active(settings.input.dynamics.active);
63 toggle_dynamics(settings.input.dynamics.active);
66 private void set_volume(double val) {
67 volume_slider.set_value(val);
68 settings.input.volume = val;
69 if (null != acm) acm.set_volume(val);
71 private void set_pregain(double val) {
72 pregain_slider.set_value(val);
73 settings.input.pregain = val;
74 if (null != acm) acm.set_pregain(val);
77 private void set_source(string name) {
80 source_selector.set_active(0, 0);
83 source_selector.set_active(0, 1);
86 source_selector.set_active(0, 2);
89 source_selector.set_active(0, 0);
92 settings.input.source = name;
93 if (null != acm) acm.set_source(name);
95 private void set_input_source(string name) {
96 settings.input.source = name;
97 if (null != acm) acm.set_source(name);
100 private void construct_interface() {
101 this.set_default_response(Gtk.ResponseType.CANCEL);
102 this.add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK);
103 this.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
105 Gtk.VBox control_area = (Gtk.VBox)this.get_content_area();
107 acm = new AudioCaptureMonitor("Recorder");
108 acm.update_level.connect(update_level_callback);
110 Gtk.HButtonBox input_bar = new Gtk.HButtonBox();
111 input_bar.set_layout(Gtk.ButtonBoxStyle.START);
112 input_bar.set_homogeneous(true);
113 input_bar.set_spacing(2);
115 source_selector = new Hildon.TouchSelector.text();
116 source_selector.append_text("Microphone");
117 source_selector.append_text("Monitor");
118 source_selector.append_text("Bluetooth");
119 //source_selector.set_active(0, 0);
120 this.set_source(settings.input.source);
121 Hildon.PickerButton source_picker = new Hildon.PickerButton(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH, Hildon.ButtonArrangement.VERTICAL);
122 source_picker.set_title("Source:");
123 source_picker.set_selector(source_selector);
124 source_picker.set_alignment(0, 0, 1, 1);
125 source_picker.set_image(new Gtk.Image.from_icon_name("camera_volume_unmuted", Gtk.IconSize.BUTTON));
126 source_picker.value_changed.connect( (s) => { set_input_source(s.get_selector().get_current_text()); } );
127 input_bar.pack_start(source_picker, true, true, 2);
129 Hildon.CheckButton audio_btn = new Hildon.CheckButton(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH);
130 audio_btn.set_label("Enable monitor");
131 //audio_btn.set_image(new Gtk.Image.from_icon_name("statusarea_volume_headset", Gtk.IconSize.BUTTON));
132 audio_btn.toggled.connect( (s) => {toggle_monitor(s.get_active());} );
133 input_bar.pack_start(audio_btn, true, false, 2);
135 control_area.pack_start(input_bar, true, true, 4);
137 Gtk.HBox monitor_1_bar = new Gtk.HBox(false, 2);
138 lbl_level_1 = new Gtk.Label(level_format.printf(0, 0));
139 monitor_1 = new DbMonitorWidget();
140 monitor_1.set_layout(DbMonitorWidget.Layout.HORIZONTAL);
141 monitor_1.set_peak(1);
142 monitor_1.set_decay(1.5);
143 monitor_1_bar.pack_start(new Gtk.Label("L"), false, false, 2);
144 monitor_1_bar.pack_start(monitor_1, true, true, 2);
145 monitor_1_bar.pack_start(lbl_level_1, false, false, 2);
146 control_area.pack_start(monitor_1_bar, true, true, 2);
148 Gtk.HBox monitor_2_bar = new Gtk.HBox(false, 4);
149 lbl_level_2 = new Gtk.Label(level_format.printf(0, 0));
150 monitor_2 = new DbMonitorWidget();
151 monitor_2.set_layout(DbMonitorWidget.Layout.HORIZONTAL);
152 monitor_2.set_peak(1);
153 monitor_2.set_decay(1.5);
154 monitor_2_bar.pack_start(new Gtk.Label("R"), false, false, 2);
155 monitor_2_bar.pack_start(monitor_2, true, true, 2);
156 monitor_2_bar.pack_start(lbl_level_2, false, false, 2);
157 control_area.pack_start(monitor_2_bar, true, true, 2);
159 Gtk.HBox pregain_bar = new Gtk.HBox(false, 4);
160 Gtk.Label pregain_label = new Gtk.Label("Pre-gain");
161 pregain_bar.pack_start(pregain_label, false, false , 2);
162 pregain_slider = new Gtk.HScale.with_range(0.0, 10.0, 0.1);
163 pregain_slider.set_value_pos(Gtk.PositionType.LEFT);
164 pregain_slider.value_changed.connect((s) => {this.set_pregain(s.get_value());});
165 pregain_bar.pack_start(pregain_slider, true, true , 2);
167 control_area.pack_start(pregain_bar, true, true , 2);
169 Gtk.HBox dynamics_bar = new Gtk.HBox(false, 4);
170 dynamics_btn = new Hildon.CheckButton(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH);
171 dynamics_btn.set_label("Enable dynamics");
172 dynamics_btn.toggled.connect( (s) => {toggle_dynamics(s.get_active());} );
173 dynamics_bar.pack_start(dynamics_btn, true, false, 2);
174 dynamics_settings_btn = new Hildon.Button(Hildon.SizeType.FINGER_HEIGHT | Hildon.SizeType.AUTO_WIDTH, Hildon.ButtonArrangement.HORIZONTAL);
175 dynamics_settings_btn.set_text("Settings", "");
176 dynamics_settings_btn.set_image(new Gtk.Image.from_icon_name("general_settings", Gtk.IconSize.BUTTON));
177 dynamics_settings_btn.set_image_position(Gtk.PositionType.LEFT);
178 dynamics_settings_btn.clicked.connect(do_dynamics_popup);
179 dynamics_bar.pack_start(dynamics_settings_btn, true, false, 2);
181 control_area.pack_start(dynamics_bar, true, true , 2);
183 Gtk.HBox volume_bar = new Gtk.HBox(false, 4);
184 Gtk.Label volume_label = new Gtk.Label("Volume");
185 volume_bar.pack_start(volume_label, false, false , 2);
186 volume_slider = new Gtk.HScale.with_range(0.0, 10.0, 0.1);
187 volume_slider.set_value_pos(Gtk.PositionType.LEFT);
188 volume_slider.value_changed.connect((s) => {this.set_volume(s.get_value());});
189 volume_bar.pack_start(volume_slider, true, true , 2);
191 control_area.pack_start(volume_bar, true, true , 2);
193 this.update_settings();
201 public void pause() {
209 private void toggle_monitor(bool state) {
211 acm.set_monitor_mute(!state);
215 private void toggle_dynamics(bool state) {
216 this.settings.input.dynamics.active = state;
217 this.dynamics_settings_btn.set_sensitive(state);
220 SettingsStructures.DynamicsSettings ds = SettingsStructures.DynamicsSettings();
221 acm.set_dynamics(ds.mode, ds.characteristics, ds.threshold, ds.ratio); // shouldn't be applied
224 acm.set_dynamics(settings.input.dynamics.mode, settings.input.dynamics.characteristics, settings.input.dynamics.threshold, settings.input.dynamics.ratio);
229 private void do_dynamics_popup() {
230 stdout.printf("dynamics popup new called\n");
232 DynamicsPopUp dlg = new DynamicsPopUp.with_settings("Monitoring dynamics settings", this, settings.input.dynamics);
233 dlg.set_transient_for(this.get_transient_for());
234 dlg.mode_updated.connect(this.dynamics_update_mode_callback);
235 dlg.characteristics_updated.connect(this.dynamics_update_characteristics_callback);
236 dlg.ratio_updated.connect(this.dynamics_update_ratio_callback);
237 dlg.threshold_updated.connect(this.dynamics_update_threshold_callback);
238 stdout.printf("dynamics connections made\n");
241 stdout.printf("dynamics back from run\n");
245 private void dynamics_update_mode_callback(DynamicsPopUp sender, string val) {
246 settings.input.dynamics.mode = val;
248 acm.set_dynamics_mode(val);
251 private void dynamics_update_characteristics_callback(DynamicsPopUp sender, string val) {
252 settings.input.dynamics.characteristics = val;
254 acm.set_dynamics_characteristics(val);
257 private void dynamics_update_ratio_callback(DynamicsPopUp sender, double val) {
258 settings.input.dynamics.ratio = val;
260 acm.set_dynamics_ratio(val);
263 private void dynamics_update_threshold_callback(DynamicsPopUp sender, double val) {
264 settings.input.dynamics.threshold = val;
266 acm.set_dynamics_threshold(val);
270 private void update_level_callback(AudioCaptureMonitor sender, int channels, int channel, double rms_dB, double peak_dB, double decay_dB, double rms) {
271 //string text = level_format.printf(channel.to_string(), rms_dB, peak_dB, decay_dB, rms, Math.pow (10, decay_dB / 20));
272 string text = level_format.printf(peak_dB, decay_dB);
274 lbl_level_1.set_text(text);
275 monitor_1.set_peak(Math.pow (10, peak_dB / 20));
276 monitor_1.set_decay(Math.pow (10, decay_dB / 20));
278 else if (1 == channel) {
279 lbl_level_2.set_text(text);
280 monitor_2.set_peak(Math.pow (10, peak_dB / 20));
281 monitor_2.set_decay(Math.pow (10, decay_dB / 20));
284 stdout.printf("channel %s found\n", channel.to_string());