, 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));
, 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());
}
set_default_response (RESPONSE_ACCEPT);
bpm_spinner.show ();
+ tap_tempo_button.show ();
+ get_vbox()->pack_end (tap_tempo_button);
set_name ("MetricDialog");
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
set_response_sensitive (RESPONSE_ACCEPT, true);
}
+void
+TempoDialog::tap_tempo ()
+{
+ gint64 now;
+ now = g_get_monotonic_time (); // microseconds
+
+ if (last_tap > 0) {
+ double interval, bpm;
+ static const double decay = 0.5;
+
+ interval = (now - last_tap) * 1.0e-6;
+ if (interval <= 6.0) {
+ // >= 10 bpm, say
+ if (average_interval > 0) {
+ average_interval = interval * decay
+ + average_interval * (1.0-decay);
+ } else {
+ average_interval = interval;
+ }
+
+ bpm = 60.0 / average_interval;
+ bpm_spinner.set_value (bpm);
+ } else {
+ average_interval = 0;
+ }
+ } else {
+ average_interval = 0;
+ }
+ last_tap = now;
+}
MeterDialog::MeterDialog (TempoMap& map, framepos_t frame, const string&)
: ArdourDialog (_("New Meter"))