1 /* Copyright 2009-2010 Yorba Foundation
3 * This software is licensed under the GNU Lesser General Public License
4 * (version 2.1 or later). See the COPYING file in this distribution.
7 public class ProjectProperties : Gtk.Dialog {
8 const int NUMBER_OF_SAMPLES = 4;
9 const long G_USEC_PER_SEC = 1000000;
11 TimeVal[] tap_time = new TimeVal[NUMBER_OF_SAMPLES];
13 bool sample_full = false;
14 Gtk.Adjustment tempo_adjustment;
15 Gtk.Adjustment volume_adjustment;
16 Gtk.ComboBox timesignature_combo;
17 Gtk.ToggleButton click_during_play;
18 Gtk.ToggleButton click_during_record;
20 public void setup(Model.Project project, Gtk.Builder builder) {
21 tempo_adjustment = (Gtk.Adjustment) builder.get_object("tempo_adjustment");
22 volume_adjustment = (Gtk.Adjustment) builder.get_object("volume_adjustment");
23 timesignature_combo = (Gtk.ComboBox) builder.get_object("timesignature_combo");
24 click_during_play = (Gtk.ToggleButton) builder.get_object("playback");
25 click_during_record = (Gtk.ToggleButton) builder.get_object("record");
26 set_tempo(project.get_bpm());
27 set_volume(project.click_volume);
28 set_during_play(project.click_during_play);
29 set_during_record(project.click_during_record);
30 set_time_signature(project.get_time_signature());
33 public void set_tempo(int tempo) {
34 tempo_adjustment.set_value(tempo);
37 public int get_tempo() {
38 return (int) tempo_adjustment.get_value();
41 public void set_volume(double volume) {
42 volume_adjustment.set_value(volume);
45 public double get_click_volume() {
46 return volume_adjustment.get_value();
49 public Fraction get_time_signature() {
50 return Fraction.from_string(timesignature_combo.get_active_text());
53 void set_time_signature(Fraction time_signature) {
54 string sig = time_signature.to_string();
57 if (timesignature_combo.model.get_iter_first(out iter)) {
60 timesignature_combo.model.get(iter, 0, out s, -1);
62 timesignature_combo.set_active_iter(iter);
65 } while (timesignature_combo.model.iter_next(ref iter));
69 void set_during_play(bool active) {
70 click_during_play.active = active;
73 public bool during_play() {
74 return click_during_play.active;
77 void set_during_record(bool active) {
78 click_during_record.active = active;
81 public bool during_record() {
82 return click_during_record.active;
85 public void on_tap() {
86 TimeVal time_val = TimeVal();
87 time_val.get_current_time();
88 tap_time[tap_index] = time_val;
90 if (tap_index == NUMBER_OF_SAMPLES) {
97 void calculate_bpm() {
98 int number_of_samples = sample_full ? NUMBER_OF_SAMPLES : tap_index;
99 if (number_of_samples < 2) {
103 int start_index = sample_full ? tap_index : 0;
105 double delta_sum = 0;
106 for (int i = 0; i < number_of_samples - 1; ++i) {
107 int current_index = (i + start_index) % NUMBER_OF_SAMPLES;
108 int next_index = (current_index + 1) % NUMBER_OF_SAMPLES;
110 (tap_time[next_index].tv_sec - tap_time[current_index].tv_sec) * G_USEC_PER_SEC +
111 tap_time[next_index].tv_usec - tap_time[current_index].tv_usec;
113 if (difference > 5 * G_USEC_PER_SEC) {
114 // User waited too long. Save the time and start over
115 tap_time[0] = tap_time[tap_index - 1];
120 delta_sum += difference;
122 double average = delta_sum/(number_of_samples - 1)/G_USEC_PER_SEC;
123 tempo_adjustment.set_value((int)(60.0/average));