tap-tempo: try to make it work properly from the very first click
authorColin Fletcher <colin.m.fletcher@googlemail.com>
Thu, 19 Mar 2015 19:44:20 +0000 (19:44 +0000)
committerColin Fletcher <colin.m.fletcher@googlemail.com>
Sat, 21 Mar 2015 12:19:25 +0000 (12:19 +0000)
gtk2_ardour/tempo_dialog.cc
gtk2_ardour/tempo_dialog.h

index e11644131b4c4bf73590154edf8d685058648711..2a353d4b7d5b9b141f61a4fa082930c0dcaefd54 100644 (file)
@@ -179,6 +179,9 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type,
        when_beat_entry.signal_key_release_event().connect (sigc::mem_fun (*this, &TempoDialog::entry_key_release), false);
        pulse_selector.signal_changed().connect (sigc::mem_fun (*this, &TempoDialog::pulse_change));
        tap_tempo_button.signal_button_press_event().connect (sigc::mem_fun (*this, &TempoDialog::tap_tempo_button_press), false);
+       tap_tempo_button.signal_focus_out_event().connect (sigc::mem_fun (*this, &TempoDialog::tap_tempo_focus_out));
+
+       tapped = false;
 }
 
 bool
@@ -262,17 +265,17 @@ TempoDialog::pulse_change ()
 bool
 TempoDialog::tap_tempo_button_press (GdkEventButton *ev)
 {
-       gint64 now;
+       guint32 now;
        now = ev->time; // milliseconds
 
-       if (last_tap > 0) {
+       if (tapped) {
                double interval, bpm;
                static const double decay = 0.5;
 
                interval = (now - last_tap) * 1.0e-3;
                if (interval <= 6.0) {
-                       // >= 10 bpm, say
-                       if (average_interval > 0) {
+                       // <= 6 seconds (say): >= 10 bpm
+                       if (average_interval > 0 && average_interval > interval / 1.2 && average_interval < interval * 1.2) {
                                average_interval = interval * decay
                                        + average_interval * (1.0-decay);
                        } else {
@@ -286,11 +289,19 @@ TempoDialog::tap_tempo_button_press (GdkEventButton *ev)
                }
        } else {
                average_interval = 0;
+               tapped = true;
        }
        last_tap = now;
        return false;
 }
 
+bool
+TempoDialog::tap_tempo_focus_out (GdkEventFocus* )
+{
+       tapped = false;
+       return false;
+}
+
 MeterDialog::MeterDialog (TempoMap& map, framepos_t frame, const string&)
        : ArdourDialog (_("New Meter"))
 {
index 67e6e6ec76fb1904cc6fd46d7968fd50eb278698..97d89e286709e1c0ce0445bfadf9603e4d10014a 100644 (file)
@@ -54,12 +54,14 @@ private:
        bool entry_key_release (GdkEventKey* );
        void pulse_change ();
        bool tap_tempo_button_press (GdkEventButton* );
+       bool tap_tempo_focus_out (GdkEventFocus* );
 
        typedef std::map<std::string,float> NoteTypes;
        NoteTypes note_types;
 
-       guint32 last_tap;
-       double average_interval;
+       bool tapped;      // whether the tap-tempo button has been clicked
+       guint32 last_tap; // time of the last tap (in mS, from GdkEventButton::time). Only valid if tapped is true
+       double average_interval; // running average of tap tempo button press interval times
 
        Gtk::ComboBoxText pulse_selector;
        Gtk::Adjustment   bpm_adjustment;