2 Copyright (C) 1999 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <cstdio> // for sprintf
23 #include <gtkmm2ext/utils.h>
25 #include <ardour/ardour.h>
26 #include <ardour/session.h>
27 #include <ardour/tempo.h>
29 #include "ardour_ui.h"
30 #include "audio_clock.h"
35 using namespace ARDOUR;
39 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
41 2, /* SMPTE_Minutes */
42 2, /* SMPTE_Seconds */
53 AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool with_tempo_and_meter)
54 : is_duration (duration),
55 editable (allow_edit),
70 audio_frames_ebox.add (audio_frames_label);
71 frames_packer_hbox.set_border_width (2);
72 frames_packer_hbox.pack_start (audio_frames_ebox, false, false);
74 hours_ebox.add (hours_label);
75 minutes_ebox.add (minutes_label);
76 seconds_ebox.add (seconds_label);
77 frames_ebox.add (frames_label);
78 bars_ebox.add (bars_label);
79 beats_ebox.add (beats_label);
80 ticks_ebox.add (ticks_label);
81 ms_hours_ebox.add (ms_hours_label);
82 ms_minutes_ebox.add (ms_minutes_label);
83 ms_seconds_ebox.add (ms_seconds_label);
85 smpte_packer.set_homogeneous (false);
86 smpte_packer.set_border_width (2);
87 smpte_packer.pack_start (hours_ebox, false, false);
88 smpte_packer.pack_start (colon1, false, false);
89 smpte_packer.pack_start (minutes_ebox, false, false);
90 smpte_packer.pack_start (colon2, false, false);
91 smpte_packer.pack_start (seconds_ebox, false, false);
92 smpte_packer.pack_start (colon3, false, false);
93 smpte_packer.pack_start (frames_ebox, false, false);
95 smpte_packer_hbox.pack_start (smpte_packer, true, false);
97 bbt_packer.set_homogeneous (false);
98 bbt_packer.set_border_width (2);
99 bbt_packer.pack_start (bars_ebox, false, false);
100 bbt_packer.pack_start (b1, false, false);
101 bbt_packer.pack_start (beats_ebox, false, false);
102 bbt_packer.pack_start (b2, false, false);
103 bbt_packer.pack_start (ticks_ebox, false, false);
105 if (with_tempo_and_meter) {
106 meter_label = manage (new Label);
107 tempo_label = manage (new Label);
109 meter_label->set_name ("BBTMeterLabel");
110 tempo_label->set_name ("BBTTempoLabel");
112 tempo_meter_box.pack_start (*meter_label, false, false);
113 tempo_meter_box.pack_start (*tempo_label, false, false);
115 bbt_packer.pack_start (tempo_meter_box, false, false, 5);
121 bbt_packer_hbox.pack_start (bbt_packer, true, false);
123 minsec_packer.set_homogeneous (false);
124 minsec_packer.set_border_width (2);
125 minsec_packer.pack_start (ms_hours_ebox, false, false);
126 minsec_packer.pack_start (colon4, false, false);
127 minsec_packer.pack_start (ms_minutes_ebox, false, false);
128 minsec_packer.pack_start (colon5, false, false);
129 minsec_packer.pack_start (ms_seconds_ebox, false, false);
131 minsec_packer_hbox.pack_start (minsec_packer, true, false);
134 clock_base.set_name (name);
136 audio_frames_label.set_name (name);
137 hours_label.set_name (name);
138 minutes_label.set_name (name);
139 seconds_label.set_name (name);
140 frames_label.set_name (name);
141 bars_label.set_name (name);
142 beats_label.set_name (name);
143 ticks_label.set_name (name);
144 ms_hours_label.set_name (name);
145 ms_minutes_label.set_name (name);
146 ms_seconds_label.set_name (name);
147 hours_ebox.set_name (name);
148 minutes_ebox.set_name (name);
149 seconds_ebox.set_name (name);
150 frames_ebox.set_name (name);
151 audio_frames_ebox.set_name (name);
152 bars_ebox.set_name (name);
153 beats_ebox.set_name (name);
154 ticks_ebox.set_name (name);
155 ms_hours_ebox.set_name (name);
156 ms_minutes_ebox.set_name (name);
157 ms_seconds_ebox.set_name (name);
159 colon1.set_name (name);
160 colon2.set_name (name);
161 colon3.set_name (name);
162 colon4.set_name (name);
163 colon5.set_name (name);
167 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
168 clock_frame.set_name ("BaseFrame");
170 clock_frame.add (clock_base);
172 _mode = BBT; /* lie to force mode switch */
175 pack_start (clock_frame, true, true);
177 /* the clock base handles button releases for menu popup regardless of
178 editable status. if the clock is editable, the clock base is where
179 we pass focus to after leaving the last editable "field", which
180 will then shutdown editing till the user starts it up again.
182 it does this because the focus out event on the field disables
183 keyboard event handling, and we don't connect anything up to
184 notice focus in on the clock base. hence, keyboard event handling
188 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
189 clock_base.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
195 set (last_when, true);
199 AudioClock::setup_events ()
201 clock_base.set_flags (Gtk::CAN_FOCUS);
203 hours_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
204 minutes_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
205 seconds_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
206 frames_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
207 bars_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
208 beats_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
209 ticks_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
210 ms_hours_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
211 ms_minutes_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
212 ms_seconds_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
213 audio_frames_ebox.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::POINTER_MOTION_MASK);
215 hours_ebox.set_flags (Gtk::CAN_FOCUS);
216 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
217 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
218 frames_ebox.set_flags (Gtk::CAN_FOCUS);
219 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
220 bars_ebox.set_flags (Gtk::CAN_FOCUS);
221 beats_ebox.set_flags (Gtk::CAN_FOCUS);
222 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
223 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
224 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
225 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
227 hours_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
228 minutes_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
229 seconds_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
230 frames_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
231 audio_frames_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), AudioFrames));
232 bars_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), Bars));
233 beats_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), Beats));
234 ticks_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), Ticks));
235 ms_hours_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), MS_Hours));
236 ms_minutes_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), MS_Minutes));
237 ms_seconds_ebox.motion_notify_event.connect (bind (slot (*this, &AudioClock::field_motion_notify_event), MS_Seconds));
239 hours_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), SMPTE_Hours));
240 minutes_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
241 seconds_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
242 frames_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), SMPTE_Frames));
243 audio_frames_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), AudioFrames));
244 bars_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), Bars));
245 beats_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), Beats));
246 ticks_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), Ticks));
247 ms_hours_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), MS_Hours));
248 ms_minutes_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), MS_Minutes));
249 ms_seconds_ebox.button_press_event.connect (bind (slot (*this, &AudioClock::field_button_press_event), MS_Seconds));
251 hours_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
252 minutes_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
253 seconds_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
254 frames_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), SMPTE_Frames));
255 audio_frames_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), AudioFrames));
256 bars_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), Bars));
257 beats_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), Beats));
258 ticks_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), Ticks));
259 ms_hours_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), MS_Hours));
260 ms_minutes_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), MS_Minutes));
261 ms_seconds_ebox.button_release_event.connect (bind (slot (*this, &AudioClock::field_button_release_event), MS_Seconds));
263 hours_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), SMPTE_Hours));
264 minutes_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
265 seconds_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
266 frames_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), SMPTE_Frames));
267 audio_frames_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), AudioFrames));
268 bars_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), Bars));
269 beats_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), Beats));
270 ticks_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), Ticks));
271 ms_hours_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), MS_Hours));
272 ms_minutes_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), MS_Minutes));
273 ms_seconds_ebox.key_release_event.connect (bind (slot (*this, &AudioClock::field_key_release_event), MS_Seconds));
275 hours_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
276 minutes_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
277 seconds_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
278 frames_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
279 audio_frames_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), AudioFrames));
280 bars_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), Bars));
281 beats_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), Beats));
282 ticks_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), Ticks));
283 ms_hours_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), MS_Hours));
284 ms_minutes_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), MS_Minutes));
285 ms_seconds_ebox.signal_focus_in_event().connect (bind (slot (*this, &AudioClock::field_focus_in_event), MS_Seconds));
287 hours_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
288 minutes_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
289 seconds_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
290 frames_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
291 audio_frames_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), AudioFrames));
292 bars_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), Bars));
293 beats_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), Beats));
294 ticks_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), Ticks));
295 ms_hours_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), MS_Hours));
296 ms_minutes_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), MS_Minutes));
297 ms_seconds_ebox.signal_focus_out_event().connect (bind (slot (*this, &AudioClock::field_focus_out_event), MS_Seconds));
299 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 0, 2);
300 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 0, 2);
301 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 0, 2);
302 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 0, 2);
304 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 0, 2);
305 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 0, 2);
306 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 0, 2);
308 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 0, 2);
312 AudioClock::realize_impl ()
314 HBox::realize_impl ();
318 AudioClock::set (jack_nframes_t when, bool force)
321 if ((!force && !is_visible()) || session == 0) {
325 if (when == last_when && !force) {
331 set_smpte (when, force);
335 set_bbt (when, force);
339 set_minsec (when, force);
343 set_frames (when, force);
354 AudioClock::set_frames (jack_nframes_t when, bool force)
357 snprintf (buf, sizeof (buf), "%u", when);
358 audio_frames_label.set_text (buf);
362 AudioClock::set_minsec (jack_nframes_t when, bool force)
371 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
372 left -= (jack_nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
373 mins = (int) floor (left / (session->frame_rate() * 60.0f));
374 left -= (jack_nframes_t) floor (mins * session->frame_rate() * 60.0f);
375 secs = left / (float) session->frame_rate();
377 if (force || hrs != ms_last_hrs) {
378 sprintf (buf, "%d", hrs);
379 ms_hours_label.set_text (buf);
383 if (force || mins != ms_last_mins) {
384 sprintf (buf, "%d", mins);
385 ms_minutes_label.set_text (buf);
389 if (force || secs != ms_last_secs) {
390 sprintf (buf, "%06.3f", secs);
391 ms_seconds_label.set_text (buf);
397 AudioClock::set_smpte (jack_nframes_t when, bool force)
403 session->smpte_duration (when, smpte);
405 session->smpte_time (when, smpte);
408 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
409 if (smpte.negative) {
410 sprintf (buf, "-%02ld", smpte.hours);
412 sprintf (buf, " %02ld", smpte.hours);
414 hours_label.set_text (buf);
415 last_hrs = smpte.hours;
416 last_negative = smpte.negative;
419 if (force || smpte.minutes != last_mins) {
420 sprintf (buf, "%02ld", smpte.minutes);
421 minutes_label.set_text (buf);
422 last_mins = smpte.minutes;
425 if (force || smpte.seconds != last_secs) {
426 sprintf (buf, "%02ld", smpte.seconds);
427 seconds_label.set_text (buf);
428 last_secs = smpte.seconds;
431 if (force || smpte.frames != last_frames) {
432 sprintf (buf, "%02ld", smpte.frames);
433 frames_label.set_text (buf);
434 last_frames = smpte.frames;
439 AudioClock::set_bbt (jack_nframes_t when, bool force)
444 session->tempo_map().bbt_time (when, bbt);
445 sprintf (buf, "%03" PRIu32, bbt.bars);
446 bars_label.set_text (buf);
447 sprintf (buf, "%02" PRIu32, bbt.beats);
448 beats_label.set_text (buf);
449 sprintf (buf, "%04" PRIu32, bbt.ticks);
450 ticks_label.set_text (buf);
453 TempoMap::Metric m (session->tempo_map().metric_at (when));
454 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
455 tempo_label->set_text (buf);
456 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
457 meter_label->set_text (buf);
462 AudioClock::set_session (Session *s)
467 set (last_when, true);
472 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
477 bool move_on = false;
481 label = &hours_label;
484 label = &minutes_label;
487 label = &seconds_label;
490 label = &frames_label;
494 label = &audio_frames_label;
498 label = &ms_hours_label;
501 label = &ms_minutes_label;
504 label = &ms_seconds_label;
511 label = &beats_label;
514 label = &ticks_label;
520 switch (ev->keyval) {
564 if (_mode == MinSec && field == MS_Seconds) {
578 clock_base.grab_focus ();
587 if (key_entry_state == 0) {
589 /* initialize with a fresh new string */
591 if (field != AudioFrames) {
592 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
601 string existing = label->get_text();
602 if (existing.length() >= field_length[field]) {
603 new_text = existing.substr (1, field_length[field] - 1);
605 new_text = existing.substr (0, field_length[field] - 1);
609 new_text += new_char;
610 label->set_text (new_text);
614 if (key_entry_state == field_length[field]) {
620 if (key_entry_state) {
627 // Check SMPTE fields for sanity (may also adjust fields)
628 smpte_sanitize_display();
634 ValueChanged(); /* EMIT_SIGNAL */
637 /* move on to the next field.
645 minutes_ebox.grab_focus ();
648 seconds_ebox.grab_focus ();
651 frames_ebox.grab_focus ();
654 clock_base.grab_focus ();
659 clock_base.grab_focus ();
665 ms_minutes_ebox.grab_focus ();
668 ms_seconds_ebox.grab_focus ();
671 clock_base.grab_focus ();
677 beats_ebox.grab_focus ();
680 ticks_ebox.grab_focus ();
683 clock_base.grab_focus ();
696 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
698 ARDOUR_UI::instance()->allow_focus (true);
704 hours_ebox.set_flags (Gtk::HAS_FOCUS);
705 hours_ebox.set_state (GTK_STATE_ACTIVE);
708 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
709 minutes_ebox.set_state (GTK_STATE_ACTIVE);
712 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
713 seconds_ebox.set_state (GTK_STATE_ACTIVE);
716 frames_ebox.set_flags (Gtk::HAS_FOCUS);
717 frames_ebox.set_state (GTK_STATE_ACTIVE);
721 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
722 audio_frames_ebox.set_state (GTK_STATE_ACTIVE);
726 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
727 ms_hours_ebox.set_state (GTK_STATE_ACTIVE);
730 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
731 ms_minutes_ebox.set_state (GTK_STATE_ACTIVE);
734 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
735 ms_seconds_ebox.set_state (GTK_STATE_ACTIVE);
738 bars_ebox.set_flags (Gtk::HAS_FOCUS);
739 bars_ebox.set_state (GTK_STATE_ACTIVE);
742 beats_ebox.set_flags (Gtk::HAS_FOCUS);
743 beats_ebox.set_state (GTK_STATE_ACTIVE);
746 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
747 ticks_ebox.set_state (GTK_STATE_ACTIVE);
755 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
757 ARDOUR_UI::instance()->allow_focus (false);
762 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
763 hours_ebox.set_state (Gtk::STATE_NORMAL);
766 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
767 minutes_ebox.set_state (Gtk::STATE_NORMAL);
770 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
771 seconds_ebox.set_state (Gtk::STATE_NORMAL);
774 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
775 frames_ebox.set_state (Gtk::STATE_NORMAL);
779 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
780 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
784 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
785 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
788 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
789 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
792 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
793 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
797 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
798 bars_ebox.set_state (Gtk::STATE_NORMAL);
801 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
802 beats_ebox.set_state (Gtk::STATE_NORMAL);
805 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
806 ticks_ebox.set_state (Gtk::STATE_NORMAL);
814 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
819 gdk_pointer_ungrab(GDK_CURRENT_TIME);
821 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
822 // we actually dragged so return without setting editing focus, or we shift clicked
832 ops_menu->popup (1, ev->time);
836 if (Keyboard::is_context_menu_event (ev)) {
840 ops_menu->popup (1, ev->time);
844 switch (ev->button) {
848 hours_ebox.grab_focus();
851 minutes_ebox.grab_focus();
854 seconds_ebox.grab_focus();
857 frames_ebox.grab_focus();
861 audio_frames_ebox.grab_focus();
865 ms_hours_ebox.grab_focus();
868 ms_minutes_ebox.grab_focus();
871 ms_seconds_ebox.grab_focus();
875 bars_ebox.grab_focus ();
878 beats_ebox.grab_focus ();
881 ticks_ebox.grab_focus ();
894 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
896 if (session == 0) return FALSE;
898 jack_nframes_t frames = 0;
900 switch (ev->button) {
902 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
904 ValueChanged (); /* EMIT_SIGNAL */
907 /* make absolutely sure that the pointer is grabbed */
908 gdk_pointer_grab(ev->window,FALSE ,
909 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
913 drag_start_y = ev->y;
918 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
920 ValueChanged (); /* EMIT_SIGNAL */
925 /* used for context sensitive menu */
930 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
931 frames = get_frames (field);
933 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
936 set (current_time() + frames, true);
937 ValueChanged (); /* EMIT_SIGNAL */
943 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
944 frames = get_frames (field);
946 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
950 if ((double)current_time() - (double)frames < 0.0) {
954 set (current_time() - frames, true);
957 ValueChanged (); /* EMIT_SIGNAL */
971 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
973 if (session == 0 || !dragging) {
977 float pixel_frame_scale_factor = 0.2f;
980 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
981 pixel_frame_scale_factor = 0.1f;
985 if (Keyboard::modifier_state_contains (ev->state,
986 Keyboard::Control|Keyboard::Alt)) {
988 pixel_frame_scale_factor = 0.025f;
991 double y_delta = ev->y - drag_y;
993 drag_accum += y_delta*pixel_frame_scale_factor;
997 if (trunc(drag_accum) != 0) {
999 jack_nframes_t frames;
1000 jack_nframes_t pos ;
1002 dir = (drag_accum < 0 ? 1:-1);
1003 pos = current_time();
1004 frames = get_frames (field,pos,dir);
1006 if (frames != 0 && frames * drag_accum < current_time()) {
1008 set ((jack_nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1016 ValueChanged(); /* EMIT_SIGNAL */
1025 AudioClock::get_frames (Field field,jack_nframes_t pos,int dir)
1028 jack_nframes_t frames = 0;
1032 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1035 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1038 frames = session->frame_rate();
1041 frames = (jack_nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second);
1049 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1052 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1055 frames = session->frame_rate();
1062 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1068 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1074 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1082 AudioClock::current_time (jack_nframes_t pos) const
1084 jack_nframes_t ret = 0;
1088 ret = smpte_frame_from_display ();
1091 ret = bbt_frame_from_display (pos);
1095 ret = minsec_frame_from_display ();
1099 ret = audio_frame_from_display ();
1110 AudioClock::current_duration (jack_nframes_t pos) const
1112 jack_nframes_t ret = 0;
1116 ret = smpte_frame_from_display ();
1119 ret = bbt_frame_duration_from_display (pos);
1123 ret = minsec_frame_from_display ();
1127 ret = audio_frame_from_display ();
1138 AudioClock::smpte_sanitize_display()
1140 // Check SMPTE fields for sanity, possibly adjusting values
1141 if (atoi(minutes_label.get_text()) > 59) {
1142 minutes_label.set_text("59");
1145 if (atoi(seconds_label.get_text()) > 59) {
1146 seconds_label.set_text("59");
1149 switch ((long)rint(session->smpte_frames_per_second)) {
1151 if (atoi(frames_label.get_text()) > 23) {
1152 frames_label.set_text("23");
1156 if (atoi(frames_label.get_text()) > 24) {
1157 frames_label.set_text("24");
1161 if (atoi(frames_label.get_text()) > 29) {
1162 frames_label.set_text("29");
1169 if (session->smpte_drop_frames) {
1170 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1171 frames_label.set_text("02");
1177 AudioClock::smpte_frame_from_display () const
1184 jack_nframes_t sample;
1186 smpte.hours = atoi (hours_label.get_text());
1187 smpte.minutes = atoi (minutes_label.get_text());
1188 smpte.seconds = atoi (seconds_label.get_text());
1189 smpte.frames = atoi (frames_label.get_text());
1191 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1195 #define SMPTE_SAMPLE_TEST_1
1196 #define SMPTE_SAMPLE_TEST_2
1197 #define SMPTE_SAMPLE_TEST_3
1198 #define SMPTE_SAMPLE_TEST_4
1199 #define SMPTE_SAMPLE_TEST_5
1200 #define SMPTE_SAMPLE_TEST_6
1201 #define SMPTE_SAMPLE_TEST_7
1203 // Testcode for smpte<->sample conversions (P.S.)
1205 jack_nframes_t sample1;
1206 jack_nframes_t oldsample = 0;
1208 jack_nframes_t sample_increment;
1210 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1212 #ifdef SMPTE_SAMPLE_TEST_1
1213 // Test 1: use_offset = false, use_subframes = false
1214 cout << "use_offset = false, use_subframes = false" << endl;
1215 for (int i = 0; i < 108003; i++) {
1216 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1217 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1219 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1220 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1221 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1222 cout << "sample: " << sample1 << endl;
1223 cout << "sample: " << sample1 << " -> ";
1224 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1228 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1229 cout << "ERROR: smpte2 not equal smpte1" << endl;
1230 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1231 cout << "sample: " << sample1 << endl;
1232 cout << "sample: " << sample1 << " -> ";
1233 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1236 oldsample = sample1;
1237 session->smpte_increment( smpte1 );
1240 cout << "sample_increment: " << sample_increment << endl;
1241 cout << "sample: " << sample1 << " -> ";
1242 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1245 #ifdef SMPTE_SAMPLE_TEST_2
1246 // Test 2: use_offset = true, use_subframes = false
1247 cout << "use_offset = true, use_subframes = false" << endl;
1253 smpte1.subframes = 0;
1254 sample1 = oldsample = 0;
1256 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1257 cout << "Starting at sample: " << sample1 << " -> ";
1258 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1260 for (int i = 0; i < 108003; i++) {
1261 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1262 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1264 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1265 // cout << "sample: " << sample1 << endl;
1266 // cout << "sample: " << sample1 << " -> ";
1267 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1269 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1270 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1271 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1272 cout << "sample: " << sample1 << endl;
1273 cout << "sample: " << sample1 << " -> ";
1274 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1278 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1279 cout << "ERROR: smpte2 not equal smpte1" << endl;
1280 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1281 cout << "sample: " << sample1 << endl;
1282 cout << "sample: " << sample1 << " -> ";
1283 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1286 oldsample = sample1;
1287 session->smpte_increment( smpte1 );
1290 cout << "sample_increment: " << sample_increment << endl;
1291 cout << "sample: " << sample1 << " -> ";
1292 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1295 #ifdef SMPTE_SAMPLE_TEST_3
1296 // Test 3: use_offset = true, use_subframes = false, decrement
1297 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1299 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1300 cout << "Starting at sample: " << sample1 << " -> ";
1301 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1303 for (int i = 0; i < 108003; i++) {
1304 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1305 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1307 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1308 // cout << "sample: " << sample1 << endl;
1309 // cout << "sample: " << sample1 << " -> ";
1310 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1312 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1313 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1314 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1315 cout << "sample: " << sample1 << endl;
1316 cout << "sample: " << sample1 << " -> ";
1317 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1321 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1322 cout << "ERROR: smpte2 not equal smpte1" << endl;
1323 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1324 cout << "sample: " << sample1 << endl;
1325 cout << "sample: " << sample1 << " -> ";
1326 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1329 oldsample = sample1;
1330 session->smpte_decrement( smpte1 );
1333 cout << "sample_decrement: " << sample_increment << endl;
1334 cout << "sample: " << sample1 << " -> ";
1335 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1339 #ifdef SMPTE_SAMPLE_TEST_4
1340 // Test 4: use_offset = true, use_subframes = true
1341 cout << "use_offset = true, use_subframes = true" << endl;
1343 for (long sub = 5; sub < 80; sub += 5) {
1348 smpte1.subframes = 0;
1349 sample1 = oldsample = (sample_increment * sub) / 80;
1351 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1353 cout << "starting at sample: " << sample1 << " -> ";
1354 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1356 for (int i = 0; i < 108003; i++) {
1357 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1358 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1360 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1361 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1362 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1363 cout << "sample: " << sample1 << endl;
1364 cout << "sample: " << sample1 << " -> ";
1365 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1369 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1370 cout << "ERROR: smpte2 not equal smpte1" << endl;
1371 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1372 cout << "sample: " << sample1 << endl;
1373 cout << "sample: " << sample1 << " -> ";
1374 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1377 oldsample = sample1;
1378 session->smpte_increment( smpte1 );
1381 cout << "sample_increment: " << sample_increment << endl;
1382 cout << "sample: " << sample1 << " -> ";
1383 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1385 for (int i = 0; i < 108003; i++) {
1386 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1387 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1389 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1390 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1391 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1392 cout << "sample: " << sample1 << endl;
1393 cout << "sample: " << sample1 << " -> ";
1394 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1398 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1399 cout << "ERROR: smpte2 not equal smpte1" << endl;
1400 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1401 cout << "sample: " << sample1 << endl;
1402 cout << "sample: " << sample1 << " -> ";
1403 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1406 oldsample = sample1;
1407 session->smpte_decrement( smpte1 );
1410 cout << "sample_decrement: " << sample_increment << endl;
1411 cout << "sample: " << sample1 << " -> ";
1412 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1417 #ifdef SMPTE_SAMPLE_TEST_5
1418 // Test 5: use_offset = true, use_subframes = false, increment seconds
1419 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1425 smpte1.subframes = 0;
1426 sample1 = oldsample = 0;
1427 sample_increment = session->frame_rate();
1429 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1430 cout << "Starting at sample: " << sample1 << " -> ";
1431 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1433 for (int i = 0; i < 3600; i++) {
1434 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1435 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1437 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1438 // cout << "sample: " << sample1 << endl;
1439 // cout << "sample: " << sample1 << " -> ";
1440 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1442 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1444 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1448 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1449 cout << "ERROR: smpte2 not equal smpte1" << endl;
1450 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1451 cout << "sample: " << sample1 << endl;
1452 cout << "sample: " << sample1 << " -> ";
1453 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1456 oldsample = sample1;
1457 session->smpte_increment_seconds( smpte1 );
1460 cout << "sample_increment: " << sample_increment << endl;
1461 cout << "sample: " << sample1 << " -> ";
1462 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1466 #ifdef SMPTE_SAMPLE_TEST_6
1467 // Test 6: use_offset = true, use_subframes = false, increment minutes
1468 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1474 smpte1.subframes = 0;
1475 sample1 = oldsample = 0;
1476 sample_increment = session->frame_rate() * 60;
1478 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1479 cout << "Starting at sample: " << sample1 << " -> ";
1480 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1482 for (int i = 0; i < 60; i++) {
1483 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1484 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1486 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1487 // cout << "sample: " << sample1 << endl;
1488 // cout << "sample: " << sample1 << " -> ";
1489 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1491 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1493 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1497 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1498 cout << "ERROR: smpte2 not equal smpte1" << endl;
1499 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1500 cout << "sample: " << sample1 << endl;
1501 cout << "sample: " << sample1 << " -> ";
1502 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1505 oldsample = sample1;
1506 session->smpte_increment_minutes( smpte1 );
1509 cout << "sample_increment: " << sample_increment << endl;
1510 cout << "sample: " << sample1 << " -> ";
1511 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1514 #ifdef SMPTE_SAMPLE_TEST_7
1515 // Test 7: use_offset = true, use_subframes = false, increment hours
1516 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1522 smpte1.subframes = 0;
1523 sample1 = oldsample = 0;
1524 sample_increment = session->frame_rate() * 60 * 60;
1526 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1527 cout << "Starting at sample: " << sample1 << " -> ";
1528 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1530 for (int i = 0; i < 10; i++) {
1531 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1532 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1534 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1535 // cout << "sample: " << sample1 << endl;
1536 // cout << "sample: " << sample1 << " -> ";
1537 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1539 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1541 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1545 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1546 cout << "ERROR: smpte2 not equal smpte1" << endl;
1547 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1548 cout << "sample: " << sample1 << endl;
1549 cout << "sample: " << sample1 << " -> ";
1550 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1553 oldsample = sample1;
1554 session->smpte_increment_hours( smpte1 );
1557 cout << "sample_increment: " << sample_increment << endl;
1558 cout << "sample: " << sample1 << " -> ";
1559 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1568 AudioClock::minsec_frame_from_display () const
1574 int hrs = atoi (ms_hours_label.get_text());
1575 int mins = atoi (ms_minutes_label.get_text());
1576 float secs = atof (ms_seconds_label.get_text());
1578 jack_nframes_t sr = session->frame_rate();
1580 return (jack_nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1584 AudioClock::bbt_frame_from_display (jack_nframes_t pos) const
1587 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1592 any.type = AnyTime::BBT;
1594 any.bbt.bars = atoi (bars_label.get_text());
1595 any.bbt.beats = atoi (beats_label.get_text());
1596 any.bbt.ticks = atoi (ticks_label.get_text());
1598 jack_nframes_t ret = session->convert_to_frames_at (pos, any);
1605 AudioClock::bbt_frame_duration_from_display (jack_nframes_t pos) const
1608 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1615 bbt.bars = atoi (bars_label.get_text());
1616 bbt.beats = atoi (beats_label.get_text());
1617 bbt.ticks = atoi (ticks_label.get_text());
1619 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1623 AudioClock::audio_frame_from_display () const
1625 return (jack_nframes_t) atoi (audio_frames_label.get_text());
1629 AudioClock::build_ops_menu ()
1631 using namespace Menu_Helpers;
1632 ops_menu = new Menu;
1633 MenuList& ops_items = ops_menu->items();
1634 ops_menu->set_name ("ArdourContextMenu");
1636 Menu *mode_menu = manage (new Menu);
1637 MenuList& mode_items = mode_menu->items();
1638 mode_menu->set_name ("ArdourContextMenu");
1640 mode_items.push_back (MenuElem (_("SMPTE"), bind (slot (*this, &AudioClock::set_mode), SMPTE)));
1641 mode_items.push_back (MenuElem (_("Bars:Beats"), bind (slot (*this, &AudioClock::set_mode), BBT)));
1642 mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (slot (*this, &AudioClock::set_mode), MinSec)));
1643 mode_items.push_back (MenuElem (_("Audio Frames"), bind (slot (*this, &AudioClock::set_mode), Frames)));
1644 mode_items.push_back (MenuElem (_("Off"), bind (slot (*this, &AudioClock::set_mode), Off)));
1646 ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1650 AudioClock::set_mode (Mode m)
1652 /* slightly tricky: this is called from within the ARDOUR_UI
1653 constructor by some of its clock members. at that time
1654 the instance pointer is unset, so we have to be careful.
1655 the main idea is to drop keyboard focus in case we had
1656 started editing the clock and then we switch clock mode.
1659 if (ARDOUR_UI::instance()) {
1660 ARDOUR_UI::instance()->allow_focus (false);
1671 clock_base.remove ();
1681 clock_base.add (smpte_packer_hbox);
1684 clock_base.add (bbt_packer_hbox);
1687 clock_base.add (minsec_packer_hbox);
1690 clock_base.add (frames_packer_hbox);
1695 set (last_when, true);
1696 clock_base.show_all ();
1697 key_entry_state = 0;