#include "gtkmm2ext/utils.h"
-#include "ardour_ui.h"
#include "tempo_dialog.h"
+#include "ui_config.h"
#include "i18n.h"
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));
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;
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;
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;
}
break;
}
}
-
+
if (x == note_types.end()) {
note_type.set_active_text (strings[3]); // "quarter"
}
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;