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>
28 #include <sigc++/bind.h>
30 #include "ardour_ui.h"
31 #include "audio_clock.h"
36 using namespace ARDOUR;
40 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
42 2, /* SMPTE_Minutes */
43 2, /* SMPTE_Seconds */
54 AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool with_tempo_and_meter)
55 : is_duration (duration),
56 editable (allow_edit),
71 audio_frames_ebox.add (audio_frames_label);
72 frames_packer_hbox.set_border_width (2);
73 frames_packer_hbox.pack_start (audio_frames_ebox, false, false);
75 hours_ebox.add (hours_label);
76 minutes_ebox.add (minutes_label);
77 seconds_ebox.add (seconds_label);
78 frames_ebox.add (frames_label);
79 bars_ebox.add (bars_label);
80 beats_ebox.add (beats_label);
81 ticks_ebox.add (ticks_label);
82 ms_hours_ebox.add (ms_hours_label);
83 ms_minutes_ebox.add (ms_minutes_label);
84 ms_seconds_ebox.add (ms_seconds_label);
86 smpte_packer.set_homogeneous (false);
87 smpte_packer.set_border_width (2);
88 smpte_packer.pack_start (hours_ebox, false, false);
89 smpte_packer.pack_start (colon1, false, false);
90 smpte_packer.pack_start (minutes_ebox, false, false);
91 smpte_packer.pack_start (colon2, false, false);
92 smpte_packer.pack_start (seconds_ebox, false, false);
93 smpte_packer.pack_start (colon3, false, false);
94 smpte_packer.pack_start (frames_ebox, false, false);
96 smpte_packer_hbox.pack_start (smpte_packer, true, false);
98 bbt_packer.set_homogeneous (false);
99 bbt_packer.set_border_width (2);
100 bbt_packer.pack_start (bars_ebox, false, false);
101 bbt_packer.pack_start (b1, false, false);
102 bbt_packer.pack_start (beats_ebox, false, false);
103 bbt_packer.pack_start (b2, false, false);
104 bbt_packer.pack_start (ticks_ebox, false, false);
106 if (with_tempo_and_meter) {
107 meter_label = manage (new Label);
108 tempo_label = manage (new Label);
110 meter_label->set_name ("BBTMeterLabel");
111 tempo_label->set_name ("BBTTempoLabel");
113 tempo_meter_box.pack_start (*meter_label, false, false);
114 tempo_meter_box.pack_start (*tempo_label, false, false);
116 bbt_packer.pack_start (tempo_meter_box, false, false, 5);
122 bbt_packer_hbox.pack_start (bbt_packer, true, false);
124 minsec_packer.set_homogeneous (false);
125 minsec_packer.set_border_width (2);
126 minsec_packer.pack_start (ms_hours_ebox, false, false);
127 minsec_packer.pack_start (colon4, false, false);
128 minsec_packer.pack_start (ms_minutes_ebox, false, false);
129 minsec_packer.pack_start (colon5, false, false);
130 minsec_packer.pack_start (ms_seconds_ebox, false, false);
132 minsec_packer_hbox.pack_start (minsec_packer, true, false);
135 clock_base.set_name (name);
137 audio_frames_label.set_name (name);
138 hours_label.set_name (name);
139 minutes_label.set_name (name);
140 seconds_label.set_name (name);
141 frames_label.set_name (name);
142 bars_label.set_name (name);
143 beats_label.set_name (name);
144 ticks_label.set_name (name);
145 ms_hours_label.set_name (name);
146 ms_minutes_label.set_name (name);
147 ms_seconds_label.set_name (name);
148 hours_ebox.set_name (name);
149 minutes_ebox.set_name (name);
150 seconds_ebox.set_name (name);
151 frames_ebox.set_name (name);
152 audio_frames_ebox.set_name (name);
153 bars_ebox.set_name (name);
154 beats_ebox.set_name (name);
155 ticks_ebox.set_name (name);
156 ms_hours_ebox.set_name (name);
157 ms_minutes_ebox.set_name (name);
158 ms_seconds_ebox.set_name (name);
160 colon1.set_name (name);
161 colon2.set_name (name);
162 colon3.set_name (name);
163 colon4.set_name (name);
164 colon5.set_name (name);
168 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
169 clock_frame.set_name ("BaseFrame");
171 clock_frame.add (clock_base);
173 _mode = BBT; /* lie to force mode switch */
176 pack_start (clock_frame, true, true);
178 /* the clock base handles button releases for menu popup regardless of
179 editable status. if the clock is editable, the clock base is where
180 we pass focus to after leaving the last editable "field", which
181 will then shutdown editing till the user starts it up again.
183 it does this because the focus out event on the field disables
184 keyboard event handling, and we don't connect anything up to
185 notice focus in on the clock base. hence, keyboard event handling
189 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
190 clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
196 set (last_when, true);
200 AudioClock::setup_events ()
202 clock_base.set_flags (Gtk::CAN_FOCUS);
204 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);
205 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);
206 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);
207 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);
208 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);
209 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);
210 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);
211 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);
212 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);
213 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);
214 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);
216 hours_ebox.set_flags (Gtk::CAN_FOCUS);
217 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
218 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
219 frames_ebox.set_flags (Gtk::CAN_FOCUS);
220 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
221 bars_ebox.set_flags (Gtk::CAN_FOCUS);
222 beats_ebox.set_flags (Gtk::CAN_FOCUS);
223 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
224 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
225 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
226 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
228 hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
229 minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
230 seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
231 frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
232 audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
233 bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
234 beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
235 ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
236 ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
237 ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
238 ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
240 hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Hours));
241 minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
242 seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
243 frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Frames));
244 audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
245 bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
246 beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
247 ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
248 ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
249 ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
250 ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
252 hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Hours));
253 minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
254 seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
255 frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Frames));
256 audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
257 bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
258 beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
259 ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
260 ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
261 ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
262 ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
264 hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours));
265 minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
266 seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
267 frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Frames));
268 audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
269 bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
270 beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
271 ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
272 ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
273 ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
274 ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
276 hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
277 minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
278 seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
279 frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
280 audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
281 bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
282 beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
283 ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
284 ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
285 ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
286 ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
288 hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
289 minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
290 seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
291 frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
292 audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
293 bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
294 beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
295 ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
296 ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
297 ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
298 ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
300 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 0, 2);
301 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 0, 2);
302 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 0, 2);
303 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 0, 2);
305 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 0, 2);
306 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 0, 2);
307 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 0, 2);
309 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 0, 2);
313 AudioClock::on_realize ()
319 AudioClock::set (jack_nframes_t when, bool force)
322 if ((!force && !is_visible()) || session == 0) {
326 if (when == last_when && !force) {
332 set_smpte (when, force);
336 set_bbt (when, force);
340 set_minsec (when, force);
344 set_frames (when, force);
355 AudioClock::set_frames (jack_nframes_t when, bool force)
358 snprintf (buf, sizeof (buf), "%u", when);
359 audio_frames_label.set_text (buf);
363 AudioClock::set_minsec (jack_nframes_t when, bool force)
372 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
373 left -= (jack_nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
374 mins = (int) floor (left / (session->frame_rate() * 60.0f));
375 left -= (jack_nframes_t) floor (mins * session->frame_rate() * 60.0f);
376 secs = left / (float) session->frame_rate();
378 if (force || hrs != ms_last_hrs) {
379 sprintf (buf, "%d", hrs);
380 ms_hours_label.set_text (buf);
384 if (force || mins != ms_last_mins) {
385 sprintf (buf, "%d", mins);
386 ms_minutes_label.set_text (buf);
390 if (force || secs != ms_last_secs) {
391 sprintf (buf, "%06.3f", secs);
392 ms_seconds_label.set_text (buf);
398 AudioClock::set_smpte (jack_nframes_t when, bool force)
404 session->smpte_duration (when, smpte);
406 session->smpte_time (when, smpte);
409 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
410 if (smpte.negative) {
411 sprintf (buf, "-%02ld", smpte.hours);
413 sprintf (buf, " %02ld", smpte.hours);
415 hours_label.set_text (buf);
416 last_hrs = smpte.hours;
417 last_negative = smpte.negative;
420 if (force || smpte.minutes != last_mins) {
421 sprintf (buf, "%02ld", smpte.minutes);
422 minutes_label.set_text (buf);
423 last_mins = smpte.minutes;
426 if (force || smpte.seconds != last_secs) {
427 sprintf (buf, "%02ld", smpte.seconds);
428 seconds_label.set_text (buf);
429 last_secs = smpte.seconds;
432 if (force || smpte.frames != last_frames) {
433 sprintf (buf, "%02ld", smpte.frames);
434 frames_label.set_text (buf);
435 last_frames = smpte.frames;
440 AudioClock::set_bbt (jack_nframes_t when, bool force)
445 session->tempo_map().bbt_time (when, bbt);
446 sprintf (buf, "%03" PRIu32, bbt.bars);
447 bars_label.set_text (buf);
448 sprintf (buf, "%02" PRIu32, bbt.beats);
449 beats_label.set_text (buf);
450 sprintf (buf, "%04" PRIu32, bbt.ticks);
451 ticks_label.set_text (buf);
454 TempoMap::Metric m (session->tempo_map().metric_at (when));
455 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
456 tempo_label->set_text (buf);
457 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
458 meter_label->set_text (buf);
463 AudioClock::set_session (Session *s)
468 set (last_when, true);
473 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
478 bool move_on = false;
482 label = &hours_label;
485 label = &minutes_label;
488 label = &seconds_label;
491 label = &frames_label;
495 label = &audio_frames_label;
499 label = &ms_hours_label;
502 label = &ms_minutes_label;
505 label = &ms_seconds_label;
512 label = &beats_label;
515 label = &ticks_label;
521 switch (ev->keyval) {
565 if (_mode == MinSec && field == MS_Seconds) {
579 clock_base.grab_focus ();
588 if (key_entry_state == 0) {
590 /* initialize with a fresh new string */
592 if (field != AudioFrames) {
593 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
602 string existing = label->get_text();
603 if (existing.length() >= field_length[field]) {
604 new_text = existing.substr (1, field_length[field] - 1);
606 new_text = existing.substr (0, field_length[field] - 1);
610 new_text += new_char;
611 label->set_text (new_text);
615 if (key_entry_state == field_length[field]) {
621 if (key_entry_state) {
628 // Check SMPTE fields for sanity (may also adjust fields)
629 smpte_sanitize_display();
635 ValueChanged(); /* EMIT_SIGNAL */
638 /* move on to the next field.
646 minutes_ebox.grab_focus ();
649 seconds_ebox.grab_focus ();
652 frames_ebox.grab_focus ();
655 clock_base.grab_focus ();
660 clock_base.grab_focus ();
666 ms_minutes_ebox.grab_focus ();
669 ms_seconds_ebox.grab_focus ();
672 clock_base.grab_focus ();
678 beats_ebox.grab_focus ();
681 ticks_ebox.grab_focus ();
684 clock_base.grab_focus ();
697 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
699 ARDOUR_UI::instance()->allow_focus (true);
705 hours_ebox.set_flags (Gtk::HAS_FOCUS);
706 hours_ebox.set_state (Gtk::STATE_ACTIVE);
709 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
710 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
713 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
714 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
717 frames_ebox.set_flags (Gtk::HAS_FOCUS);
718 frames_ebox.set_state (Gtk::STATE_ACTIVE);
722 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
723 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
727 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
728 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
731 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
732 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
735 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
736 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
739 bars_ebox.set_flags (Gtk::HAS_FOCUS);
740 bars_ebox.set_state (Gtk::STATE_ACTIVE);
743 beats_ebox.set_flags (Gtk::HAS_FOCUS);
744 beats_ebox.set_state (Gtk::STATE_ACTIVE);
747 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
748 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
756 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
758 ARDOUR_UI::instance()->allow_focus (false);
763 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
764 hours_ebox.set_state (Gtk::STATE_NORMAL);
767 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
768 minutes_ebox.set_state (Gtk::STATE_NORMAL);
771 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
772 seconds_ebox.set_state (Gtk::STATE_NORMAL);
775 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
776 frames_ebox.set_state (Gtk::STATE_NORMAL);
780 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
781 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
785 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
786 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
789 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
790 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
793 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
794 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
798 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
799 bars_ebox.set_state (Gtk::STATE_NORMAL);
802 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
803 beats_ebox.set_state (Gtk::STATE_NORMAL);
806 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
807 ticks_ebox.set_state (Gtk::STATE_NORMAL);
815 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
820 gdk_pointer_ungrab(GDK_CURRENT_TIME);
822 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
823 // we actually dragged so return without setting editing focus, or we shift clicked
833 ops_menu->popup (1, ev->time);
837 if (Keyboard::is_context_menu_event (ev)) {
841 ops_menu->popup (1, ev->time);
845 switch (ev->button) {
849 hours_ebox.grab_focus();
852 minutes_ebox.grab_focus();
855 seconds_ebox.grab_focus();
858 frames_ebox.grab_focus();
862 audio_frames_ebox.grab_focus();
866 ms_hours_ebox.grab_focus();
869 ms_minutes_ebox.grab_focus();
872 ms_seconds_ebox.grab_focus();
876 bars_ebox.grab_focus ();
879 beats_ebox.grab_focus ();
882 ticks_ebox.grab_focus ();
895 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
897 if (session == 0) return FALSE;
899 jack_nframes_t frames = 0;
901 switch (ev->button) {
903 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
905 ValueChanged (); /* EMIT_SIGNAL */
908 /* make absolutely sure that the pointer is grabbed */
909 gdk_pointer_grab(ev->window,FALSE ,
910 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
914 drag_start_y = ev->y;
919 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
921 ValueChanged (); /* EMIT_SIGNAL */
926 /* used for context sensitive menu */
931 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
932 frames = get_frames (field);
934 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
937 set (current_time() + frames, true);
938 ValueChanged (); /* EMIT_SIGNAL */
944 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
945 frames = get_frames (field);
947 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
951 if ((double)current_time() - (double)frames < 0.0) {
955 set (current_time() - frames, true);
958 ValueChanged (); /* EMIT_SIGNAL */
972 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
974 if (session == 0 || !dragging) {
978 float pixel_frame_scale_factor = 0.2f;
981 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
982 pixel_frame_scale_factor = 0.1f;
986 if (Keyboard::modifier_state_contains (ev->state,
987 Keyboard::Control|Keyboard::Alt)) {
989 pixel_frame_scale_factor = 0.025f;
992 double y_delta = ev->y - drag_y;
994 drag_accum += y_delta*pixel_frame_scale_factor;
998 if (trunc(drag_accum) != 0) {
1000 jack_nframes_t frames;
1001 jack_nframes_t pos ;
1003 dir = (drag_accum < 0 ? 1:-1);
1004 pos = current_time();
1005 frames = get_frames (field,pos,dir);
1007 if (frames != 0 && frames * drag_accum < current_time()) {
1009 set ((jack_nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1017 ValueChanged(); /* EMIT_SIGNAL */
1026 AudioClock::get_frames (Field field,jack_nframes_t pos,int dir)
1029 jack_nframes_t frames = 0;
1033 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1036 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1039 frames = session->frame_rate();
1042 frames = (jack_nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second);
1050 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1053 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1056 frames = session->frame_rate();
1063 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1069 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1075 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1083 AudioClock::current_time (jack_nframes_t pos) const
1085 jack_nframes_t ret = 0;
1089 ret = smpte_frame_from_display ();
1092 ret = bbt_frame_from_display (pos);
1096 ret = minsec_frame_from_display ();
1100 ret = audio_frame_from_display ();
1111 AudioClock::current_duration (jack_nframes_t pos) const
1113 jack_nframes_t ret = 0;
1117 ret = smpte_frame_from_display ();
1120 ret = bbt_frame_duration_from_display (pos);
1124 ret = minsec_frame_from_display ();
1128 ret = audio_frame_from_display ();
1139 AudioClock::smpte_sanitize_display()
1141 // Check SMPTE fields for sanity, possibly adjusting values
1142 if (atoi(minutes_label.get_text()) > 59) {
1143 minutes_label.set_text("59");
1146 if (atoi(seconds_label.get_text()) > 59) {
1147 seconds_label.set_text("59");
1150 switch ((long)rint(session->smpte_frames_per_second)) {
1152 if (atoi(frames_label.get_text()) > 23) {
1153 frames_label.set_text("23");
1157 if (atoi(frames_label.get_text()) > 24) {
1158 frames_label.set_text("24");
1162 if (atoi(frames_label.get_text()) > 29) {
1163 frames_label.set_text("29");
1170 if (session->smpte_drop_frames) {
1171 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1172 frames_label.set_text("02");
1178 AudioClock::smpte_frame_from_display () const
1185 jack_nframes_t sample;
1187 smpte.hours = atoi (hours_label.get_text());
1188 smpte.minutes = atoi (minutes_label.get_text());
1189 smpte.seconds = atoi (seconds_label.get_text());
1190 smpte.frames = atoi (frames_label.get_text());
1192 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1196 #define SMPTE_SAMPLE_TEST_1
1197 #define SMPTE_SAMPLE_TEST_2
1198 #define SMPTE_SAMPLE_TEST_3
1199 #define SMPTE_SAMPLE_TEST_4
1200 #define SMPTE_SAMPLE_TEST_5
1201 #define SMPTE_SAMPLE_TEST_6
1202 #define SMPTE_SAMPLE_TEST_7
1204 // Testcode for smpte<->sample conversions (P.S.)
1206 jack_nframes_t sample1;
1207 jack_nframes_t oldsample = 0;
1209 jack_nframes_t sample_increment;
1211 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1213 #ifdef SMPTE_SAMPLE_TEST_1
1214 // Test 1: use_offset = false, use_subframes = false
1215 cout << "use_offset = false, use_subframes = false" << endl;
1216 for (int i = 0; i < 108003; i++) {
1217 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1218 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1220 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1221 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1222 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1223 cout << "sample: " << sample1 << endl;
1224 cout << "sample: " << sample1 << " -> ";
1225 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1229 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1230 cout << "ERROR: smpte2 not equal smpte1" << endl;
1231 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1232 cout << "sample: " << sample1 << endl;
1233 cout << "sample: " << sample1 << " -> ";
1234 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1237 oldsample = sample1;
1238 session->smpte_increment( smpte1 );
1241 cout << "sample_increment: " << sample_increment << endl;
1242 cout << "sample: " << sample1 << " -> ";
1243 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1246 #ifdef SMPTE_SAMPLE_TEST_2
1247 // Test 2: use_offset = true, use_subframes = false
1248 cout << "use_offset = true, use_subframes = false" << endl;
1254 smpte1.subframes = 0;
1255 sample1 = oldsample = 0;
1257 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1258 cout << "Starting at sample: " << sample1 << " -> ";
1259 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1261 for (int i = 0; i < 108003; i++) {
1262 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1263 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1265 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1266 // cout << "sample: " << sample1 << endl;
1267 // cout << "sample: " << sample1 << " -> ";
1268 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1270 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1271 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1272 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1273 cout << "sample: " << sample1 << endl;
1274 cout << "sample: " << sample1 << " -> ";
1275 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1279 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1280 cout << "ERROR: smpte2 not equal smpte1" << endl;
1281 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1282 cout << "sample: " << sample1 << endl;
1283 cout << "sample: " << sample1 << " -> ";
1284 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1287 oldsample = sample1;
1288 session->smpte_increment( smpte1 );
1291 cout << "sample_increment: " << sample_increment << endl;
1292 cout << "sample: " << sample1 << " -> ";
1293 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1296 #ifdef SMPTE_SAMPLE_TEST_3
1297 // Test 3: use_offset = true, use_subframes = false, decrement
1298 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1300 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1301 cout << "Starting at sample: " << sample1 << " -> ";
1302 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1304 for (int i = 0; i < 108003; i++) {
1305 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1306 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1308 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1309 // cout << "sample: " << sample1 << endl;
1310 // cout << "sample: " << sample1 << " -> ";
1311 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1313 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1314 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1315 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1316 cout << "sample: " << sample1 << endl;
1317 cout << "sample: " << sample1 << " -> ";
1318 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1322 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1323 cout << "ERROR: smpte2 not equal smpte1" << endl;
1324 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1325 cout << "sample: " << sample1 << endl;
1326 cout << "sample: " << sample1 << " -> ";
1327 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1330 oldsample = sample1;
1331 session->smpte_decrement( smpte1 );
1334 cout << "sample_decrement: " << sample_increment << endl;
1335 cout << "sample: " << sample1 << " -> ";
1336 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1340 #ifdef SMPTE_SAMPLE_TEST_4
1341 // Test 4: use_offset = true, use_subframes = true
1342 cout << "use_offset = true, use_subframes = true" << endl;
1344 for (long sub = 5; sub < 80; sub += 5) {
1349 smpte1.subframes = 0;
1350 sample1 = oldsample = (sample_increment * sub) / 80;
1352 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1354 cout << "starting at sample: " << sample1 << " -> ";
1355 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1357 for (int i = 0; i < 108003; i++) {
1358 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1359 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1361 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1362 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1363 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1364 cout << "sample: " << sample1 << endl;
1365 cout << "sample: " << sample1 << " -> ";
1366 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1370 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1371 cout << "ERROR: smpte2 not equal smpte1" << endl;
1372 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1373 cout << "sample: " << sample1 << endl;
1374 cout << "sample: " << sample1 << " -> ";
1375 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1378 oldsample = sample1;
1379 session->smpte_increment( smpte1 );
1382 cout << "sample_increment: " << sample_increment << endl;
1383 cout << "sample: " << sample1 << " -> ";
1384 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1386 for (int i = 0; i < 108003; i++) {
1387 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1388 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1390 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1391 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1392 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1393 cout << "sample: " << sample1 << endl;
1394 cout << "sample: " << sample1 << " -> ";
1395 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1399 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1400 cout << "ERROR: smpte2 not equal smpte1" << endl;
1401 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1402 cout << "sample: " << sample1 << endl;
1403 cout << "sample: " << sample1 << " -> ";
1404 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1407 oldsample = sample1;
1408 session->smpte_decrement( smpte1 );
1411 cout << "sample_decrement: " << sample_increment << endl;
1412 cout << "sample: " << sample1 << " -> ";
1413 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1418 #ifdef SMPTE_SAMPLE_TEST_5
1419 // Test 5: use_offset = true, use_subframes = false, increment seconds
1420 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1426 smpte1.subframes = 0;
1427 sample1 = oldsample = 0;
1428 sample_increment = session->frame_rate();
1430 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1431 cout << "Starting at sample: " << sample1 << " -> ";
1432 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1434 for (int i = 0; i < 3600; i++) {
1435 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1436 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1438 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1439 // cout << "sample: " << sample1 << endl;
1440 // cout << "sample: " << sample1 << " -> ";
1441 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1443 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1445 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1449 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1450 cout << "ERROR: smpte2 not equal smpte1" << endl;
1451 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1452 cout << "sample: " << sample1 << endl;
1453 cout << "sample: " << sample1 << " -> ";
1454 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1457 oldsample = sample1;
1458 session->smpte_increment_seconds( smpte1 );
1461 cout << "sample_increment: " << sample_increment << endl;
1462 cout << "sample: " << sample1 << " -> ";
1463 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1467 #ifdef SMPTE_SAMPLE_TEST_6
1468 // Test 6: use_offset = true, use_subframes = false, increment minutes
1469 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1475 smpte1.subframes = 0;
1476 sample1 = oldsample = 0;
1477 sample_increment = session->frame_rate() * 60;
1479 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1480 cout << "Starting at sample: " << sample1 << " -> ";
1481 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1483 for (int i = 0; i < 60; i++) {
1484 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1485 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1487 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1488 // cout << "sample: " << sample1 << endl;
1489 // cout << "sample: " << sample1 << " -> ";
1490 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1492 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1494 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1498 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1499 cout << "ERROR: smpte2 not equal smpte1" << endl;
1500 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1501 cout << "sample: " << sample1 << endl;
1502 cout << "sample: " << sample1 << " -> ";
1503 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1506 oldsample = sample1;
1507 session->smpte_increment_minutes( smpte1 );
1510 cout << "sample_increment: " << sample_increment << endl;
1511 cout << "sample: " << sample1 << " -> ";
1512 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1515 #ifdef SMPTE_SAMPLE_TEST_7
1516 // Test 7: use_offset = true, use_subframes = false, increment hours
1517 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1523 smpte1.subframes = 0;
1524 sample1 = oldsample = 0;
1525 sample_increment = session->frame_rate() * 60 * 60;
1527 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1528 cout << "Starting at sample: " << sample1 << " -> ";
1529 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1531 for (int i = 0; i < 10; i++) {
1532 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1533 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1535 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1536 // cout << "sample: " << sample1 << endl;
1537 // cout << "sample: " << sample1 << " -> ";
1538 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1540 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1542 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1546 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1547 cout << "ERROR: smpte2 not equal smpte1" << endl;
1548 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1549 cout << "sample: " << sample1 << endl;
1550 cout << "sample: " << sample1 << " -> ";
1551 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1554 oldsample = sample1;
1555 session->smpte_increment_hours( smpte1 );
1558 cout << "sample_increment: " << sample_increment << endl;
1559 cout << "sample: " << sample1 << " -> ";
1560 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1569 AudioClock::minsec_frame_from_display () const
1575 int hrs = atoi (ms_hours_label.get_text());
1576 int mins = atoi (ms_minutes_label.get_text());
1577 float secs = atof (ms_seconds_label.get_text());
1579 jack_nframes_t sr = session->frame_rate();
1581 return (jack_nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1585 AudioClock::bbt_frame_from_display (jack_nframes_t pos) const
1588 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1593 any.type = AnyTime::BBT;
1595 any.bbt.bars = atoi (bars_label.get_text());
1596 any.bbt.beats = atoi (beats_label.get_text());
1597 any.bbt.ticks = atoi (ticks_label.get_text());
1599 jack_nframes_t ret = session->convert_to_frames_at (pos, any);
1606 AudioClock::bbt_frame_duration_from_display (jack_nframes_t pos) const
1609 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1616 bbt.bars = atoi (bars_label.get_text());
1617 bbt.beats = atoi (beats_label.get_text());
1618 bbt.ticks = atoi (ticks_label.get_text());
1620 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1624 AudioClock::audio_frame_from_display () const
1626 return (jack_nframes_t) atoi (audio_frames_label.get_text());
1630 AudioClock::build_ops_menu ()
1632 using namespace Menu_Helpers;
1633 ops_menu = new Menu;
1634 MenuList& ops_items = ops_menu->items();
1635 ops_menu->set_name ("ArdourContextMenu");
1637 Menu *mode_menu = manage (new Menu);
1638 MenuList& mode_items = mode_menu->items();
1639 mode_menu->set_name ("ArdourContextMenu");
1641 mode_items.push_back (MenuElem (_("SMPTE"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1642 mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1643 mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1644 mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1645 mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1647 ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1651 AudioClock::set_mode (Mode m)
1653 /* slightly tricky: this is called from within the ARDOUR_UI
1654 constructor by some of its clock members. at that time
1655 the instance pointer is unset, so we have to be careful.
1656 the main idea is to drop keyboard focus in case we had
1657 started editing the clock and then we switch clock mode.
1660 if (ARDOUR_UI::instance()) {
1661 ARDOUR_UI::instance()->allow_focus (false);
1672 clock_base.remove ();
1682 clock_base.add (smpte_packer_hbox);
1685 clock_base.add (bbt_packer_hbox);
1688 clock_base.add (minsec_packer_hbox);
1691 clock_base.add (frames_packer_hbox);
1696 set (last_when, true);
1697 clock_base.show_all ();
1698 key_entry_state = 0;