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));
302 AudioClock::on_realize ()
306 /* styles are not available until the widgets are bound to a window */
310 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 0, 2);
311 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 0, 2);
312 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 0, 2);
313 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 0, 2);
317 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 0, 2);
318 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 0, 2);
319 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 0, 2);
323 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "99", 0, 2);
324 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "99", 0, 2);
325 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "99", 0, 2);
329 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 0, 2);
335 AudioClock::set (jack_nframes_t when, bool force)
338 if ((!force && !is_visible()) || session == 0) {
342 if (when == last_when && !force) {
348 set_smpte (when, force);
352 set_bbt (when, force);
356 set_minsec (when, force);
360 set_frames (when, force);
371 AudioClock::set_frames (jack_nframes_t when, bool force)
374 snprintf (buf, sizeof (buf), "%u", when);
375 audio_frames_label.set_text (buf);
379 AudioClock::set_minsec (jack_nframes_t when, bool force)
388 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
389 left -= (jack_nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
390 mins = (int) floor (left / (session->frame_rate() * 60.0f));
391 left -= (jack_nframes_t) floor (mins * session->frame_rate() * 60.0f);
392 secs = left / (float) session->frame_rate();
394 if (force || hrs != ms_last_hrs) {
395 sprintf (buf, "%d", hrs);
396 ms_hours_label.set_text (buf);
400 if (force || mins != ms_last_mins) {
401 sprintf (buf, "%d", mins);
402 ms_minutes_label.set_text (buf);
406 if (force || secs != ms_last_secs) {
407 sprintf (buf, "%06.3f", secs);
408 ms_seconds_label.set_text (buf);
414 AudioClock::set_smpte (jack_nframes_t when, bool force)
420 session->smpte_duration (when, smpte);
422 session->smpte_time (when, smpte);
425 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
426 if (smpte.negative) {
427 sprintf (buf, "-%02ld", smpte.hours);
429 sprintf (buf, " %02ld", smpte.hours);
431 hours_label.set_text (buf);
432 last_hrs = smpte.hours;
433 last_negative = smpte.negative;
436 if (force || smpte.minutes != last_mins) {
437 sprintf (buf, "%02ld", smpte.minutes);
438 minutes_label.set_text (buf);
439 last_mins = smpte.minutes;
442 if (force || smpte.seconds != last_secs) {
443 sprintf (buf, "%02ld", smpte.seconds);
444 seconds_label.set_text (buf);
445 last_secs = smpte.seconds;
448 if (force || smpte.frames != last_frames) {
449 sprintf (buf, "%02ld", smpte.frames);
450 frames_label.set_text (buf);
451 last_frames = smpte.frames;
456 AudioClock::set_bbt (jack_nframes_t when, bool force)
461 session->tempo_map().bbt_time (when, bbt);
462 sprintf (buf, "%03" PRIu32, bbt.bars);
463 bars_label.set_text (buf);
464 sprintf (buf, "%02" PRIu32, bbt.beats);
465 beats_label.set_text (buf);
466 sprintf (buf, "%04" PRIu32, bbt.ticks);
467 ticks_label.set_text (buf);
470 TempoMap::Metric m (session->tempo_map().metric_at (when));
471 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
472 tempo_label->set_text (buf);
473 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
474 meter_label->set_text (buf);
479 AudioClock::set_session (Session *s)
484 set (last_when, true);
489 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
494 bool move_on = false;
498 label = &hours_label;
501 label = &minutes_label;
504 label = &seconds_label;
507 label = &frames_label;
511 label = &audio_frames_label;
515 label = &ms_hours_label;
518 label = &ms_minutes_label;
521 label = &ms_seconds_label;
528 label = &beats_label;
531 label = &ticks_label;
537 switch (ev->keyval) {
581 if (_mode == MinSec && field == MS_Seconds) {
595 clock_base.grab_focus ();
604 if (key_entry_state == 0) {
606 /* initialize with a fresh new string */
608 if (field != AudioFrames) {
609 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
618 string existing = label->get_text();
619 if (existing.length() >= field_length[field]) {
620 new_text = existing.substr (1, field_length[field] - 1);
622 new_text = existing.substr (0, field_length[field] - 1);
626 new_text += new_char;
627 label->set_text (new_text);
631 if (key_entry_state == field_length[field]) {
637 if (key_entry_state) {
644 // Check SMPTE fields for sanity (may also adjust fields)
645 smpte_sanitize_display();
651 ValueChanged(); /* EMIT_SIGNAL */
654 /* move on to the next field.
662 minutes_ebox.grab_focus ();
665 seconds_ebox.grab_focus ();
668 frames_ebox.grab_focus ();
671 clock_base.grab_focus ();
676 clock_base.grab_focus ();
682 ms_minutes_ebox.grab_focus ();
685 ms_seconds_ebox.grab_focus ();
688 clock_base.grab_focus ();
694 beats_ebox.grab_focus ();
697 ticks_ebox.grab_focus ();
700 clock_base.grab_focus ();
713 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
719 hours_ebox.set_flags (Gtk::HAS_FOCUS);
720 hours_ebox.set_state (Gtk::STATE_ACTIVE);
723 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
724 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
727 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
728 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
731 frames_ebox.set_flags (Gtk::HAS_FOCUS);
732 frames_ebox.set_state (Gtk::STATE_ACTIVE);
736 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
737 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
741 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
742 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
745 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
746 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
749 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
750 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
753 bars_ebox.set_flags (Gtk::HAS_FOCUS);
754 bars_ebox.set_state (Gtk::STATE_ACTIVE);
757 beats_ebox.set_flags (Gtk::HAS_FOCUS);
758 beats_ebox.set_state (Gtk::STATE_ACTIVE);
761 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
762 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
770 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
775 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
776 hours_ebox.set_state (Gtk::STATE_NORMAL);
779 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
780 minutes_ebox.set_state (Gtk::STATE_NORMAL);
783 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
784 seconds_ebox.set_state (Gtk::STATE_NORMAL);
787 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
788 frames_ebox.set_state (Gtk::STATE_NORMAL);
792 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
793 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
797 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
798 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
801 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
802 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
805 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
806 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
810 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
811 bars_ebox.set_state (Gtk::STATE_NORMAL);
814 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
815 beats_ebox.set_state (Gtk::STATE_NORMAL);
818 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
819 ticks_ebox.set_state (Gtk::STATE_NORMAL);
827 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
832 gdk_pointer_ungrab(GDK_CURRENT_TIME);
834 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
835 // we actually dragged so return without setting editing focus, or we shift clicked
845 ops_menu->popup (1, ev->time);
849 if (Keyboard::is_context_menu_event (ev)) {
853 ops_menu->popup (1, ev->time);
857 switch (ev->button) {
861 hours_ebox.grab_focus();
864 minutes_ebox.grab_focus();
867 seconds_ebox.grab_focus();
870 frames_ebox.grab_focus();
874 audio_frames_ebox.grab_focus();
878 ms_hours_ebox.grab_focus();
881 ms_minutes_ebox.grab_focus();
884 ms_seconds_ebox.grab_focus();
888 bars_ebox.grab_focus ();
891 beats_ebox.grab_focus ();
894 ticks_ebox.grab_focus ();
907 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
909 if (session == 0) return FALSE;
911 jack_nframes_t frames = 0;
913 switch (ev->button) {
915 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
917 ValueChanged (); /* EMIT_SIGNAL */
920 /* make absolutely sure that the pointer is grabbed */
921 gdk_pointer_grab(ev->window,FALSE ,
922 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
926 drag_start_y = ev->y;
931 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
933 ValueChanged (); /* EMIT_SIGNAL */
938 /* used for context sensitive menu */
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)) {
949 set (current_time() + frames, true);
950 ValueChanged (); /* EMIT_SIGNAL */
956 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
957 frames = get_frames (field);
959 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
963 if ((double)current_time() - (double)frames < 0.0) {
967 set (current_time() - frames, true);
970 ValueChanged (); /* EMIT_SIGNAL */
984 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
986 if (session == 0 || !dragging) {
990 float pixel_frame_scale_factor = 0.2f;
993 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
994 pixel_frame_scale_factor = 0.1f;
998 if (Keyboard::modifier_state_contains (ev->state,
999 Keyboard::Control|Keyboard::Alt)) {
1001 pixel_frame_scale_factor = 0.025f;
1004 double y_delta = ev->y - drag_y;
1006 drag_accum += y_delta*pixel_frame_scale_factor;
1010 if (trunc(drag_accum) != 0) {
1012 jack_nframes_t frames;
1013 jack_nframes_t pos ;
1015 dir = (drag_accum < 0 ? 1:-1);
1016 pos = current_time();
1017 frames = get_frames (field,pos,dir);
1019 if (frames != 0 && frames * drag_accum < current_time()) {
1021 set ((jack_nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1029 ValueChanged(); /* EMIT_SIGNAL */
1038 AudioClock::get_frames (Field field,jack_nframes_t pos,int dir)
1041 jack_nframes_t frames = 0;
1045 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1048 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1051 frames = session->frame_rate();
1054 frames = (jack_nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second);
1062 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1065 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1068 frames = session->frame_rate();
1075 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1081 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1087 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1095 AudioClock::current_time (jack_nframes_t pos) const
1097 jack_nframes_t ret = 0;
1101 ret = smpte_frame_from_display ();
1104 ret = bbt_frame_from_display (pos);
1108 ret = minsec_frame_from_display ();
1112 ret = audio_frame_from_display ();
1123 AudioClock::current_duration (jack_nframes_t pos) const
1125 jack_nframes_t ret = 0;
1129 ret = smpte_frame_from_display ();
1132 ret = bbt_frame_duration_from_display (pos);
1136 ret = minsec_frame_from_display ();
1140 ret = audio_frame_from_display ();
1151 AudioClock::smpte_sanitize_display()
1153 // Check SMPTE fields for sanity, possibly adjusting values
1154 if (atoi(minutes_label.get_text()) > 59) {
1155 minutes_label.set_text("59");
1158 if (atoi(seconds_label.get_text()) > 59) {
1159 seconds_label.set_text("59");
1162 switch ((long)rint(session->smpte_frames_per_second)) {
1164 if (atoi(frames_label.get_text()) > 23) {
1165 frames_label.set_text("23");
1169 if (atoi(frames_label.get_text()) > 24) {
1170 frames_label.set_text("24");
1174 if (atoi(frames_label.get_text()) > 29) {
1175 frames_label.set_text("29");
1182 if (session->smpte_drop_frames) {
1183 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1184 frames_label.set_text("02");
1190 AudioClock::smpte_frame_from_display () const
1197 jack_nframes_t sample;
1199 smpte.hours = atoi (hours_label.get_text());
1200 smpte.minutes = atoi (minutes_label.get_text());
1201 smpte.seconds = atoi (seconds_label.get_text());
1202 smpte.frames = atoi (frames_label.get_text());
1204 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1208 #define SMPTE_SAMPLE_TEST_1
1209 #define SMPTE_SAMPLE_TEST_2
1210 #define SMPTE_SAMPLE_TEST_3
1211 #define SMPTE_SAMPLE_TEST_4
1212 #define SMPTE_SAMPLE_TEST_5
1213 #define SMPTE_SAMPLE_TEST_6
1214 #define SMPTE_SAMPLE_TEST_7
1216 // Testcode for smpte<->sample conversions (P.S.)
1218 jack_nframes_t sample1;
1219 jack_nframes_t oldsample = 0;
1221 jack_nframes_t sample_increment;
1223 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1225 #ifdef SMPTE_SAMPLE_TEST_1
1226 // Test 1: use_offset = false, use_subframes = false
1227 cout << "use_offset = false, use_subframes = false" << endl;
1228 for (int i = 0; i < 108003; i++) {
1229 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1230 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1232 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1233 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1234 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1235 cout << "sample: " << sample1 << endl;
1236 cout << "sample: " << sample1 << " -> ";
1237 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1241 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1242 cout << "ERROR: smpte2 not equal smpte1" << endl;
1243 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1244 cout << "sample: " << sample1 << endl;
1245 cout << "sample: " << sample1 << " -> ";
1246 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1249 oldsample = sample1;
1250 session->smpte_increment( smpte1 );
1253 cout << "sample_increment: " << sample_increment << endl;
1254 cout << "sample: " << sample1 << " -> ";
1255 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1258 #ifdef SMPTE_SAMPLE_TEST_2
1259 // Test 2: use_offset = true, use_subframes = false
1260 cout << "use_offset = true, use_subframes = false" << endl;
1266 smpte1.subframes = 0;
1267 sample1 = oldsample = 0;
1269 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1270 cout << "Starting at sample: " << sample1 << " -> ";
1271 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1273 for (int i = 0; i < 108003; i++) {
1274 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1275 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1277 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1278 // cout << "sample: " << sample1 << endl;
1279 // cout << "sample: " << sample1 << " -> ";
1280 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1282 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1283 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1284 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1285 cout << "sample: " << sample1 << endl;
1286 cout << "sample: " << sample1 << " -> ";
1287 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1291 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1292 cout << "ERROR: smpte2 not equal smpte1" << endl;
1293 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1294 cout << "sample: " << sample1 << endl;
1295 cout << "sample: " << sample1 << " -> ";
1296 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1299 oldsample = sample1;
1300 session->smpte_increment( smpte1 );
1303 cout << "sample_increment: " << sample_increment << endl;
1304 cout << "sample: " << sample1 << " -> ";
1305 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1308 #ifdef SMPTE_SAMPLE_TEST_3
1309 // Test 3: use_offset = true, use_subframes = false, decrement
1310 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1312 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1313 cout << "Starting at sample: " << sample1 << " -> ";
1314 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1316 for (int i = 0; i < 108003; i++) {
1317 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1318 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1320 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1321 // cout << "sample: " << sample1 << endl;
1322 // cout << "sample: " << sample1 << " -> ";
1323 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1325 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1326 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1327 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1328 cout << "sample: " << sample1 << endl;
1329 cout << "sample: " << sample1 << " -> ";
1330 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1334 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1335 cout << "ERROR: smpte2 not equal smpte1" << endl;
1336 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1337 cout << "sample: " << sample1 << endl;
1338 cout << "sample: " << sample1 << " -> ";
1339 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1342 oldsample = sample1;
1343 session->smpte_decrement( smpte1 );
1346 cout << "sample_decrement: " << sample_increment << endl;
1347 cout << "sample: " << sample1 << " -> ";
1348 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1352 #ifdef SMPTE_SAMPLE_TEST_4
1353 // Test 4: use_offset = true, use_subframes = true
1354 cout << "use_offset = true, use_subframes = true" << endl;
1356 for (long sub = 5; sub < 80; sub += 5) {
1361 smpte1.subframes = 0;
1362 sample1 = oldsample = (sample_increment * sub) / 80;
1364 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1366 cout << "starting at sample: " << sample1 << " -> ";
1367 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1369 for (int i = 0; i < 108003; i++) {
1370 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1371 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1373 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1374 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1375 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1376 cout << "sample: " << sample1 << endl;
1377 cout << "sample: " << sample1 << " -> ";
1378 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1382 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1383 cout << "ERROR: smpte2 not equal smpte1" << endl;
1384 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1385 cout << "sample: " << sample1 << endl;
1386 cout << "sample: " << sample1 << " -> ";
1387 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1390 oldsample = sample1;
1391 session->smpte_increment( smpte1 );
1394 cout << "sample_increment: " << sample_increment << endl;
1395 cout << "sample: " << sample1 << " -> ";
1396 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1398 for (int i = 0; i < 108003; i++) {
1399 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1400 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1402 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1403 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1404 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1405 cout << "sample: " << sample1 << endl;
1406 cout << "sample: " << sample1 << " -> ";
1407 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1411 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1412 cout << "ERROR: smpte2 not equal smpte1" << endl;
1413 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1414 cout << "sample: " << sample1 << endl;
1415 cout << "sample: " << sample1 << " -> ";
1416 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1419 oldsample = sample1;
1420 session->smpte_decrement( smpte1 );
1423 cout << "sample_decrement: " << sample_increment << endl;
1424 cout << "sample: " << sample1 << " -> ";
1425 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1430 #ifdef SMPTE_SAMPLE_TEST_5
1431 // Test 5: use_offset = true, use_subframes = false, increment seconds
1432 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1438 smpte1.subframes = 0;
1439 sample1 = oldsample = 0;
1440 sample_increment = session->frame_rate();
1442 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1443 cout << "Starting at sample: " << sample1 << " -> ";
1444 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1446 for (int i = 0; i < 3600; i++) {
1447 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1448 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
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;
1455 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1457 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1461 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1462 cout << "ERROR: smpte2 not equal smpte1" << endl;
1463 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1464 cout << "sample: " << sample1 << endl;
1465 cout << "sample: " << sample1 << " -> ";
1466 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1469 oldsample = sample1;
1470 session->smpte_increment_seconds( smpte1 );
1473 cout << "sample_increment: " << sample_increment << endl;
1474 cout << "sample: " << sample1 << " -> ";
1475 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1479 #ifdef SMPTE_SAMPLE_TEST_6
1480 // Test 6: use_offset = true, use_subframes = false, increment minutes
1481 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1487 smpte1.subframes = 0;
1488 sample1 = oldsample = 0;
1489 sample_increment = session->frame_rate() * 60;
1491 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1492 cout << "Starting at sample: " << sample1 << " -> ";
1493 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1495 for (int i = 0; i < 60; i++) {
1496 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1497 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
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;
1504 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1506 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1510 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1511 cout << "ERROR: smpte2 not equal smpte1" << endl;
1512 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1513 cout << "sample: " << sample1 << endl;
1514 cout << "sample: " << sample1 << " -> ";
1515 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1518 oldsample = sample1;
1519 session->smpte_increment_minutes( smpte1 );
1522 cout << "sample_increment: " << sample_increment << endl;
1523 cout << "sample: " << sample1 << " -> ";
1524 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1527 #ifdef SMPTE_SAMPLE_TEST_7
1528 // Test 7: use_offset = true, use_subframes = false, increment hours
1529 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1535 smpte1.subframes = 0;
1536 sample1 = oldsample = 0;
1537 sample_increment = session->frame_rate() * 60 * 60;
1539 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1540 cout << "Starting at sample: " << sample1 << " -> ";
1541 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1543 for (int i = 0; i < 10; i++) {
1544 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1545 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
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;
1552 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1554 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1558 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1559 cout << "ERROR: smpte2 not equal smpte1" << endl;
1560 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1561 cout << "sample: " << sample1 << endl;
1562 cout << "sample: " << sample1 << " -> ";
1563 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1566 oldsample = sample1;
1567 session->smpte_increment_hours( smpte1 );
1570 cout << "sample_increment: " << sample_increment << endl;
1571 cout << "sample: " << sample1 << " -> ";
1572 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1581 AudioClock::minsec_frame_from_display () const
1587 int hrs = atoi (ms_hours_label.get_text());
1588 int mins = atoi (ms_minutes_label.get_text());
1589 float secs = atof (ms_seconds_label.get_text());
1591 jack_nframes_t sr = session->frame_rate();
1593 return (jack_nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1597 AudioClock::bbt_frame_from_display (jack_nframes_t pos) const
1600 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1605 any.type = AnyTime::BBT;
1607 any.bbt.bars = atoi (bars_label.get_text());
1608 any.bbt.beats = atoi (beats_label.get_text());
1609 any.bbt.ticks = atoi (ticks_label.get_text());
1611 jack_nframes_t ret = session->convert_to_frames_at (pos, any);
1618 AudioClock::bbt_frame_duration_from_display (jack_nframes_t pos) const
1621 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1628 bbt.bars = atoi (bars_label.get_text());
1629 bbt.beats = atoi (beats_label.get_text());
1630 bbt.ticks = atoi (ticks_label.get_text());
1632 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1636 AudioClock::audio_frame_from_display () const
1638 return (jack_nframes_t) atoi (audio_frames_label.get_text());
1642 AudioClock::build_ops_menu ()
1644 using namespace Menu_Helpers;
1645 ops_menu = new Menu;
1646 MenuList& ops_items = ops_menu->items();
1647 ops_menu->set_name ("ArdourContextMenu");
1649 Menu *mode_menu = manage (new Menu);
1650 MenuList& mode_items = mode_menu->items();
1651 mode_menu->set_name ("ArdourContextMenu");
1653 mode_items.push_back (MenuElem (_("SMPTE"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1654 mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1655 mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1656 mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1657 mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1659 ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1663 AudioClock::set_mode (Mode m)
1665 /* slightly tricky: this is called from within the ARDOUR_UI
1666 constructor by some of its clock members. at that time
1667 the instance pointer is unset, so we have to be careful.
1668 the main idea is to drop keyboard focus in case we had
1669 started editing the clock and then we switch clock mode.
1672 // GTK2FIX might need an equivalent here for drop focus
1683 clock_base.remove ();
1693 clock_base.add (smpte_packer_hbox);
1694 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 0, 2);
1695 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 0, 2);
1696 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 0, 2);
1697 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 0, 2);
1701 clock_base.add (bbt_packer_hbox);
1702 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 0, 2);
1703 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 0, 2);
1704 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 0, 2);
1708 clock_base.add (minsec_packer_hbox);
1709 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "99", 0, 2);
1710 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "99", 0, 2);
1711 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "99", 0, 2);
1715 clock_base.add (frames_packer_hbox);
1716 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 0, 2);
1722 set (last_when, true);
1723 clock_base.show_all ();
1724 key_entry_state = 0;