From e0eaea6471e25f4c3797450a96f35fcdbb1c6992 Mon Sep 17 00:00:00 2001 From: Colin Fletcher Date: Mon, 10 Feb 2014 21:14:59 +0000 Subject: Add 'Tap tempo' button to 'Edit tempo' dialogue Add a 'Tap tempo' button to the 'Edit tempo' dialogue box that uses gettimeofday() to time the interval between successive clicks and sets the beats-per-minute appropriately. --- gtk2_ardour/tempo_dialog.cc | 26 ++++++++++++++++++++++++++ gtk2_ardour/tempo_dialog.h | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc index 7c0e510aff..9173393ff5 100644 --- a/gtk2_ardour/tempo_dialog.cc +++ b/gtk2_ardour/tempo_dialog.cc @@ -42,6 +42,7 @@ TempoDialog::TempoDialog (TempoMap& map, framepos_t frame, const string&) , when_bar_label (_("bar:"), ALIGN_LEFT, ALIGN_CENTER) , when_beat_label (_("beat:"), ALIGN_LEFT, ALIGN_CENTER) , pulse_selector_label (_("Pulse note"), ALIGN_LEFT, ALIGN_CENTER) + , tap_tempo_button (_("Tap tempo")) { Timecode::BBT_Time when; Tempo tempo (map.tempo_at (frame)); @@ -57,6 +58,7 @@ TempoDialog::TempoDialog (TempoSection& section, const string&) , when_bar_label (_("bar:"), ALIGN_LEFT, ALIGN_CENTER) , when_beat_label (_("beat:"), ALIGN_LEFT, ALIGN_CENTER) , pulse_selector_label (_("Pulse note"), ALIGN_LEFT, ALIGN_CENTER) + , tap_tempo_button (_("Tap tempo")) { init (section.start(), section.beats_per_minute(), section.note_type(), section.movable()); } @@ -162,6 +164,8 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type, set_default_response (RESPONSE_ACCEPT); bpm_spinner.show (); + tap_tempo_button.show (); + get_vbox()->pack_end (tap_tempo_button); set_name ("MetricDialog"); @@ -174,6 +178,7 @@ TempoDialog::init (const Timecode::BBT_Time& when, double bpm, double note_type, when_beat_entry.signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT)); 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_clicked().connect (sigc::mem_fun (*this, &TempoDialog::tap_tempo)); } void @@ -249,6 +254,27 @@ TempoDialog::pulse_change () set_response_sensitive (RESPONSE_ACCEPT, true); } +void +TempoDialog::tap_tempo () +{ + struct timeval now; + gettimeofday (&now, NULL); + + if (last_tap.tv_sec >= 0 || last_tap.tv_usec > 0) { + struct timeval diff; + double interval, bpm; + timersub (&now, &last_tap, &diff); + interval = diff.tv_sec + diff.tv_usec * 1.0e-6; + + bpm = 60.0 / interval; + if (bpm >= 20) { + bpm_spinner.set_value (bpm); + } + } + last_tap = now; + + +} MeterDialog::MeterDialog (TempoMap& map, framepos_t frame, const string&) : ArdourDialog (_("New Meter")) diff --git a/gtk2_ardour/tempo_dialog.h b/gtk2_ardour/tempo_dialog.h index ba269a4425..848b55cb59 100644 --- a/gtk2_ardour/tempo_dialog.h +++ b/gtk2_ardour/tempo_dialog.h @@ -52,10 +52,13 @@ private: bool bpm_button_release (GdkEventButton* ); bool entry_key_release (GdkEventKey* ); void pulse_change (); + void tap_tempo (); typedef std::map NoteTypes; NoteTypes note_types; + struct timeval last_tap; + Gtk::ComboBoxText pulse_selector; Gtk::Adjustment bpm_adjustment; Gtk::SpinButton bpm_spinner; @@ -64,6 +67,7 @@ private: Gtk::Label when_bar_label; Gtk::Label when_beat_label; Gtk::Label pulse_selector_label; + Gtk::Button tap_tempo_button; }; class MeterDialog : public ArdourDialog -- cgit v1.2.3