fix compilation on OSX/PPC (old coreaudio)
[ardour.git] / gtk2_ardour / tempo_dialog.cc
index a458c4220ad1869978bb032d794f911591352d90..a7a6f4ae759e90d00b535404a748d1c01ff0325b 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "gtkmm2ext/utils.h"
 
-#include "ardour_ui.h"
 #include "tempo_dialog.h"
+#include "ui_config.h"
 
 #include "i18n.h"
 
@@ -105,10 +105,10 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type,
        if (x == note_types.end()) {
                pulse_selector.set_active_text (strings[3]); // "quarter"
        }
-       
+
        Table* table;
 
-       if (ARDOUR_UI::config()->get_allow_non_quarter_pulse()) {
+       if (UIConfiguration::instance().get_allow_non_quarter_pulse()) {
                table = manage (new Table (5, 5));
        } else {
                table = manage (new Table (5, 4));
@@ -122,7 +122,7 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type,
        table->attach (*bpm_label, 0, 1, 0, 1);
        table->attach (bpm_spinner, 1, 5, 0, 1);
 
-       if (ARDOUR_UI::config()->get_allow_non_quarter_pulse()) {
+       if (UIConfiguration::instance().get_allow_non_quarter_pulse()) {
                table->attach (pulse_selector_label, 0, 1, 1, 2);
                table->attach (pulse_selector, 1, 5, 1, 2);
                row = 2;
@@ -249,7 +249,7 @@ double
 TempoDialog::get_note_type ()
 {
        NoteTypes::iterator x = note_types.find (pulse_selector.get_active_text());
-       
+
        if (x == note_types.end()) {
                error << string_compose(_("incomprehensible pulse note type (%1)"), pulse_selector.get_active_text()) << endmsg;
                return 0;
@@ -267,39 +267,38 @@ TempoDialog::pulse_change ()
 bool
 TempoDialog::tap_tempo_button_press (GdkEventButton *ev)
 {
-       gint64 now;
-       now = g_get_monotonic_time (); // microseconds
+       double t;
 
+       // Linear least-squares regression
        if (tapped) {
-               double interval, bpm;
-               static const double decay = 0.5;
-
-               interval = (now - last_tap) * 1.0e-6;
-               if (interval <= 6.0) {
-                       // <= 6 seconds (say): >= 10 bpm
-                       if (average_interval > 0) {
-                               if (average_interval > interval / 1.2 && average_interval < interval * 1.2) {
-                               average_interval = interval * decay
-                                       + average_interval * (1.0-decay);
-                               } else {
-                                       average_interval = 0;
-                               }
-                       } else {
-                               average_interval = interval;
-                       }
-
-                       if (average_interval > 0) {
-                               bpm = 60.0 / average_interval;
-                               bpm_spinner.set_value (bpm);
-                       }
+               t = 1e-6 * (g_get_monotonic_time () - first_t); // Subtract first_t to avoid precision problems
+
+               double n = tap_count;
+               sum_y += t;
+               sum_x += n;
+               sum_xy += n * t;
+               sum_xx += n * n;
+               double T = (sum_xy/n - sum_x/n * sum_y/n) / (sum_xx/n - sum_x/n * sum_x/n);
+
+               if (t - last_t < T / 1.2 || t - last_t > T * 1.2) {
+                       tapped = false;
                } else {
-                       average_interval = 0;
+                       bpm_spinner.set_value (60.0 / T);
                }
-       } else {
-               average_interval = 0;
+       }
+       if (!tapped) {
+               first_t = g_get_monotonic_time ();
+               t = 0.0;
+               sum_y = 0.0;
+               sum_x = 1.0;
+               sum_xy = 0.0;
+               sum_xx = 1.0;
+               tap_count = 1.0;
+
                tapped = true;
        }
-       last_tap = now;
+       tap_count++;
+       last_t = t;
 
        return true;
 }
@@ -367,7 +366,7 @@ MeterDialog::init (const Timecode::BBT_Time& when, double bpb, double divisor, b
                        break;
                }
        }
-       
+
        if (x == note_types.end()) {
                note_type.set_active_text (strings[3]); // "quarter"
        }
@@ -498,7 +497,7 @@ double
 MeterDialog::get_note_type ()
 {
        NoteTypes::iterator x = note_types.find (note_type.get_active_text());
-       
+
        if (x == note_types.end()) {
                error << string_compose(_("incomprehensible meter note type (%1)"), note_type.get_active_text()) << endmsg;
                return 0;