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, true, true);
114 tempo_meter_box.pack_start (*tempo_label, true, true);
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);
339 AudioClock::set (jack_nframes_t when, bool force)
342 if ((!force && !is_visible()) || session == 0) {
346 if (when == last_when && !force) {
352 set_smpte (when, force);
356 set_bbt (when, force);
360 set_minsec (when, force);
364 set_frames (when, force);
375 AudioClock::set_frames (jack_nframes_t when, bool force)
378 snprintf (buf, sizeof (buf), "%u", when);
379 audio_frames_label.set_text (buf);
383 AudioClock::set_minsec (jack_nframes_t when, bool force)
392 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
393 left -= (jack_nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
394 mins = (int) floor (left / (session->frame_rate() * 60.0f));
395 left -= (jack_nframes_t) floor (mins * session->frame_rate() * 60.0f);
396 secs = left / (float) session->frame_rate();
398 if (force || hrs != ms_last_hrs) {
399 sprintf (buf, "%d", hrs);
400 ms_hours_label.set_text (buf);
404 if (force || mins != ms_last_mins) {
405 sprintf (buf, "%d", mins);
406 ms_minutes_label.set_text (buf);
410 if (force || secs != ms_last_secs) {
411 sprintf (buf, "%06.3f", secs);
412 ms_seconds_label.set_text (buf);
418 AudioClock::set_smpte (jack_nframes_t when, bool force)
424 session->smpte_duration (when, smpte);
426 session->smpte_time (when, smpte);
429 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
430 if (smpte.negative) {
431 sprintf (buf, "-%02ld", smpte.hours);
433 sprintf (buf, " %02ld", smpte.hours);
435 hours_label.set_text (buf);
436 last_hrs = smpte.hours;
437 last_negative = smpte.negative;
440 if (force || smpte.minutes != last_mins) {
441 sprintf (buf, "%02ld", smpte.minutes);
442 minutes_label.set_text (buf);
443 last_mins = smpte.minutes;
446 if (force || smpte.seconds != last_secs) {
447 sprintf (buf, "%02ld", smpte.seconds);
448 seconds_label.set_text (buf);
449 last_secs = smpte.seconds;
452 if (force || smpte.frames != last_frames) {
453 sprintf (buf, "%02ld", smpte.frames);
454 frames_label.set_text (buf);
455 last_frames = smpte.frames;
460 AudioClock::set_bbt (jack_nframes_t when, bool force)
465 session->tempo_map().bbt_time (when, bbt);
466 sprintf (buf, "%03" PRIu32, bbt.bars);
467 bars_label.set_text (buf);
468 sprintf (buf, "%02" PRIu32, bbt.beats);
469 beats_label.set_text (buf);
470 sprintf (buf, "%04" PRIu32, bbt.ticks);
471 ticks_label.set_text (buf);
474 TempoMap::Metric m (session->tempo_map().metric_at (when));
475 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
476 tempo_label->set_text (buf);
477 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
478 meter_label->set_text (buf);
483 AudioClock::set_session (Session *s)
488 set (last_when, true);
493 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
498 bool move_on = false;
502 label = &hours_label;
505 label = &minutes_label;
508 label = &seconds_label;
511 label = &frames_label;
515 label = &audio_frames_label;
519 label = &ms_hours_label;
522 label = &ms_minutes_label;
525 label = &ms_seconds_label;
532 label = &beats_label;
535 label = &ticks_label;
541 switch (ev->keyval) {
585 if (_mode == MinSec && field == MS_Seconds) {
599 clock_base.grab_focus ();
608 if (key_entry_state == 0) {
610 /* initialize with a fresh new string */
612 if (field != AudioFrames) {
613 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
622 string existing = label->get_text();
623 if (existing.length() >= field_length[field]) {
624 new_text = existing.substr (1, field_length[field] - 1);
626 new_text = existing.substr (0, field_length[field] - 1);
630 new_text += new_char;
631 label->set_text (new_text);
635 if (key_entry_state == field_length[field]) {
641 if (key_entry_state) {
648 // Check SMPTE fields for sanity (may also adjust fields)
649 smpte_sanitize_display();
655 ValueChanged(); /* EMIT_SIGNAL */
658 /* move on to the next field.
666 minutes_ebox.grab_focus ();
669 seconds_ebox.grab_focus ();
672 frames_ebox.grab_focus ();
675 clock_base.grab_focus ();
680 clock_base.grab_focus ();
686 ms_minutes_ebox.grab_focus ();
689 ms_seconds_ebox.grab_focus ();
692 clock_base.grab_focus ();
698 beats_ebox.grab_focus ();
701 ticks_ebox.grab_focus ();
704 clock_base.grab_focus ();
717 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
723 hours_ebox.set_flags (Gtk::HAS_FOCUS);
724 hours_ebox.set_state (Gtk::STATE_ACTIVE);
727 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
728 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
731 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
732 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
735 frames_ebox.set_flags (Gtk::HAS_FOCUS);
736 frames_ebox.set_state (Gtk::STATE_ACTIVE);
740 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
741 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
745 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
746 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
749 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
750 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
753 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
754 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
757 bars_ebox.set_flags (Gtk::HAS_FOCUS);
758 bars_ebox.set_state (Gtk::STATE_ACTIVE);
761 beats_ebox.set_flags (Gtk::HAS_FOCUS);
762 beats_ebox.set_state (Gtk::STATE_ACTIVE);
765 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
766 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
774 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
779 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
780 hours_ebox.set_state (Gtk::STATE_NORMAL);
783 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
784 minutes_ebox.set_state (Gtk::STATE_NORMAL);
787 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
788 seconds_ebox.set_state (Gtk::STATE_NORMAL);
791 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
792 frames_ebox.set_state (Gtk::STATE_NORMAL);
796 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
797 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
801 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
802 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
805 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
806 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
809 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
810 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
814 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
815 bars_ebox.set_state (Gtk::STATE_NORMAL);
818 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
819 beats_ebox.set_state (Gtk::STATE_NORMAL);
822 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
823 ticks_ebox.set_state (Gtk::STATE_NORMAL);
831 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
836 gdk_pointer_ungrab(GDK_CURRENT_TIME);
838 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
839 // we actually dragged so return without setting editing focus, or we shift clicked
849 ops_menu->popup (1, ev->time);
853 if (Keyboard::is_context_menu_event (ev)) {
857 ops_menu->popup (1, ev->time);
861 switch (ev->button) {
865 hours_ebox.grab_focus();
868 minutes_ebox.grab_focus();
871 seconds_ebox.grab_focus();
874 frames_ebox.grab_focus();
878 audio_frames_ebox.grab_focus();
882 ms_hours_ebox.grab_focus();
885 ms_minutes_ebox.grab_focus();
888 ms_seconds_ebox.grab_focus();
892 bars_ebox.grab_focus ();
895 beats_ebox.grab_focus ();
898 ticks_ebox.grab_focus ();
911 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
913 if (session == 0) return FALSE;
915 jack_nframes_t frames = 0;
917 switch (ev->button) {
919 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
921 ValueChanged (); /* EMIT_SIGNAL */
924 /* make absolutely sure that the pointer is grabbed */
925 gdk_pointer_grab(ev->window,FALSE ,
926 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
930 drag_start_y = ev->y;
935 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
937 ValueChanged (); /* EMIT_SIGNAL */
942 /* used for context sensitive menu */
947 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
948 frames = get_frames (field);
950 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
953 set (current_time() + frames, true);
954 ValueChanged (); /* EMIT_SIGNAL */
960 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
961 frames = get_frames (field);
963 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
967 if ((double)current_time() - (double)frames < 0.0) {
971 set (current_time() - frames, true);
974 ValueChanged (); /* EMIT_SIGNAL */
988 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
990 if (session == 0 || !dragging) {
994 float pixel_frame_scale_factor = 0.2f;
997 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
998 pixel_frame_scale_factor = 0.1f;
1002 if (Keyboard::modifier_state_contains (ev->state,
1003 Keyboard::Control|Keyboard::Alt)) {
1005 pixel_frame_scale_factor = 0.025f;
1008 double y_delta = ev->y - drag_y;
1010 drag_accum += y_delta*pixel_frame_scale_factor;
1014 if (trunc(drag_accum) != 0) {
1016 jack_nframes_t frames;
1017 jack_nframes_t pos ;
1019 dir = (drag_accum < 0 ? 1:-1);
1020 pos = current_time();
1021 frames = get_frames (field,pos,dir);
1023 if (frames != 0 && frames * drag_accum < current_time()) {
1025 set ((jack_nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1033 ValueChanged(); /* EMIT_SIGNAL */
1042 AudioClock::get_frames (Field field,jack_nframes_t pos,int dir)
1045 jack_nframes_t frames = 0;
1049 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1052 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1055 frames = session->frame_rate();
1058 frames = (jack_nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second);
1066 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1069 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1072 frames = session->frame_rate();
1079 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1085 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1091 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1099 AudioClock::current_time (jack_nframes_t pos) const
1101 jack_nframes_t ret = 0;
1105 ret = smpte_frame_from_display ();
1108 ret = bbt_frame_from_display (pos);
1112 ret = minsec_frame_from_display ();
1116 ret = audio_frame_from_display ();
1127 AudioClock::current_duration (jack_nframes_t pos) const
1129 jack_nframes_t ret = 0;
1133 ret = smpte_frame_from_display ();
1136 ret = bbt_frame_duration_from_display (pos);
1140 ret = minsec_frame_from_display ();
1144 ret = audio_frame_from_display ();
1155 AudioClock::smpte_sanitize_display()
1157 // Check SMPTE fields for sanity, possibly adjusting values
1158 if (atoi(minutes_label.get_text()) > 59) {
1159 minutes_label.set_text("59");
1162 if (atoi(seconds_label.get_text()) > 59) {
1163 seconds_label.set_text("59");
1166 switch ((long)rint(session->smpte_frames_per_second)) {
1168 if (atoi(frames_label.get_text()) > 23) {
1169 frames_label.set_text("23");
1173 if (atoi(frames_label.get_text()) > 24) {
1174 frames_label.set_text("24");
1178 if (atoi(frames_label.get_text()) > 29) {
1179 frames_label.set_text("29");
1186 if (session->smpte_drop_frames) {
1187 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1188 frames_label.set_text("02");
1194 AudioClock::smpte_frame_from_display () const
1201 jack_nframes_t sample;
1203 smpte.hours = atoi (hours_label.get_text());
1204 smpte.minutes = atoi (minutes_label.get_text());
1205 smpte.seconds = atoi (seconds_label.get_text());
1206 smpte.frames = atoi (frames_label.get_text());
1208 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1212 #define SMPTE_SAMPLE_TEST_1
1213 #define SMPTE_SAMPLE_TEST_2
1214 #define SMPTE_SAMPLE_TEST_3
1215 #define SMPTE_SAMPLE_TEST_4
1216 #define SMPTE_SAMPLE_TEST_5
1217 #define SMPTE_SAMPLE_TEST_6
1218 #define SMPTE_SAMPLE_TEST_7
1220 // Testcode for smpte<->sample conversions (P.S.)
1222 jack_nframes_t sample1;
1223 jack_nframes_t oldsample = 0;
1225 jack_nframes_t sample_increment;
1227 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1229 #ifdef SMPTE_SAMPLE_TEST_1
1230 // Test 1: use_offset = false, use_subframes = false
1231 cout << "use_offset = false, use_subframes = false" << endl;
1232 for (int i = 0; i < 108003; i++) {
1233 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1234 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1236 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1237 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1238 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1239 cout << "sample: " << sample1 << endl;
1240 cout << "sample: " << sample1 << " -> ";
1241 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1245 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1246 cout << "ERROR: smpte2 not equal smpte1" << endl;
1247 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1248 cout << "sample: " << sample1 << endl;
1249 cout << "sample: " << sample1 << " -> ";
1250 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1253 oldsample = sample1;
1254 session->smpte_increment( smpte1 );
1257 cout << "sample_increment: " << sample_increment << endl;
1258 cout << "sample: " << sample1 << " -> ";
1259 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1262 #ifdef SMPTE_SAMPLE_TEST_2
1263 // Test 2: use_offset = true, use_subframes = false
1264 cout << "use_offset = true, use_subframes = false" << endl;
1270 smpte1.subframes = 0;
1271 sample1 = oldsample = 0;
1273 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1274 cout << "Starting at sample: " << sample1 << " -> ";
1275 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1277 for (int i = 0; i < 108003; i++) {
1278 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1279 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1281 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1282 // cout << "sample: " << sample1 << endl;
1283 // cout << "sample: " << sample1 << " -> ";
1284 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1286 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1287 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1288 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1289 cout << "sample: " << sample1 << endl;
1290 cout << "sample: " << sample1 << " -> ";
1291 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1295 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1296 cout << "ERROR: smpte2 not equal smpte1" << endl;
1297 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1298 cout << "sample: " << sample1 << endl;
1299 cout << "sample: " << sample1 << " -> ";
1300 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1303 oldsample = sample1;
1304 session->smpte_increment( smpte1 );
1307 cout << "sample_increment: " << sample_increment << endl;
1308 cout << "sample: " << sample1 << " -> ";
1309 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1312 #ifdef SMPTE_SAMPLE_TEST_3
1313 // Test 3: use_offset = true, use_subframes = false, decrement
1314 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1316 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1317 cout << "Starting at sample: " << sample1 << " -> ";
1318 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1320 for (int i = 0; i < 108003; i++) {
1321 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1322 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1324 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1325 // cout << "sample: " << sample1 << endl;
1326 // cout << "sample: " << sample1 << " -> ";
1327 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1329 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1330 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1331 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1332 cout << "sample: " << sample1 << endl;
1333 cout << "sample: " << sample1 << " -> ";
1334 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1338 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1339 cout << "ERROR: smpte2 not equal smpte1" << endl;
1340 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1341 cout << "sample: " << sample1 << endl;
1342 cout << "sample: " << sample1 << " -> ";
1343 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1346 oldsample = sample1;
1347 session->smpte_decrement( smpte1 );
1350 cout << "sample_decrement: " << sample_increment << endl;
1351 cout << "sample: " << sample1 << " -> ";
1352 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1356 #ifdef SMPTE_SAMPLE_TEST_4
1357 // Test 4: use_offset = true, use_subframes = true
1358 cout << "use_offset = true, use_subframes = true" << endl;
1360 for (long sub = 5; sub < 80; sub += 5) {
1365 smpte1.subframes = 0;
1366 sample1 = oldsample = (sample_increment * sub) / 80;
1368 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1370 cout << "starting at sample: " << sample1 << " -> ";
1371 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1373 for (int i = 0; i < 108003; i++) {
1374 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1375 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1377 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1378 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1379 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1380 cout << "sample: " << sample1 << endl;
1381 cout << "sample: " << sample1 << " -> ";
1382 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1386 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1387 cout << "ERROR: smpte2 not equal smpte1" << endl;
1388 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1389 cout << "sample: " << sample1 << endl;
1390 cout << "sample: " << sample1 << " -> ";
1391 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1394 oldsample = sample1;
1395 session->smpte_increment( smpte1 );
1398 cout << "sample_increment: " << sample_increment << endl;
1399 cout << "sample: " << sample1 << " -> ";
1400 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1402 for (int i = 0; i < 108003; i++) {
1403 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1404 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1406 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1407 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1408 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1409 cout << "sample: " << sample1 << endl;
1410 cout << "sample: " << sample1 << " -> ";
1411 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1415 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1416 cout << "ERROR: smpte2 not equal smpte1" << endl;
1417 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1418 cout << "sample: " << sample1 << endl;
1419 cout << "sample: " << sample1 << " -> ";
1420 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1423 oldsample = sample1;
1424 session->smpte_decrement( smpte1 );
1427 cout << "sample_decrement: " << sample_increment << endl;
1428 cout << "sample: " << sample1 << " -> ";
1429 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1434 #ifdef SMPTE_SAMPLE_TEST_5
1435 // Test 5: use_offset = true, use_subframes = false, increment seconds
1436 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1442 smpte1.subframes = 0;
1443 sample1 = oldsample = 0;
1444 sample_increment = session->frame_rate();
1446 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1447 cout << "Starting at sample: " << sample1 << " -> ";
1448 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1450 for (int i = 0; i < 3600; i++) {
1451 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1452 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1454 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1455 // cout << "sample: " << sample1 << endl;
1456 // cout << "sample: " << sample1 << " -> ";
1457 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1459 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1461 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1465 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1466 cout << "ERROR: smpte2 not equal smpte1" << endl;
1467 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1468 cout << "sample: " << sample1 << endl;
1469 cout << "sample: " << sample1 << " -> ";
1470 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1473 oldsample = sample1;
1474 session->smpte_increment_seconds( smpte1 );
1477 cout << "sample_increment: " << sample_increment << endl;
1478 cout << "sample: " << sample1 << " -> ";
1479 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1483 #ifdef SMPTE_SAMPLE_TEST_6
1484 // Test 6: use_offset = true, use_subframes = false, increment minutes
1485 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1491 smpte1.subframes = 0;
1492 sample1 = oldsample = 0;
1493 sample_increment = session->frame_rate() * 60;
1495 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1496 cout << "Starting at sample: " << sample1 << " -> ";
1497 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1499 for (int i = 0; i < 60; i++) {
1500 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1501 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1503 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1504 // cout << "sample: " << sample1 << endl;
1505 // cout << "sample: " << sample1 << " -> ";
1506 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1508 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1510 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1514 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1515 cout << "ERROR: smpte2 not equal smpte1" << endl;
1516 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1517 cout << "sample: " << sample1 << endl;
1518 cout << "sample: " << sample1 << " -> ";
1519 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1522 oldsample = sample1;
1523 session->smpte_increment_minutes( smpte1 );
1526 cout << "sample_increment: " << sample_increment << endl;
1527 cout << "sample: " << sample1 << " -> ";
1528 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1531 #ifdef SMPTE_SAMPLE_TEST_7
1532 // Test 7: use_offset = true, use_subframes = false, increment hours
1533 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1539 smpte1.subframes = 0;
1540 sample1 = oldsample = 0;
1541 sample_increment = session->frame_rate() * 60 * 60;
1543 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1544 cout << "Starting at sample: " << sample1 << " -> ";
1545 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1547 for (int i = 0; i < 10; i++) {
1548 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1549 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1551 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1552 // cout << "sample: " << sample1 << endl;
1553 // cout << "sample: " << sample1 << " -> ";
1554 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1556 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1558 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1562 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1563 cout << "ERROR: smpte2 not equal smpte1" << endl;
1564 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1565 cout << "sample: " << sample1 << endl;
1566 cout << "sample: " << sample1 << " -> ";
1567 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1570 oldsample = sample1;
1571 session->smpte_increment_hours( smpte1 );
1574 cout << "sample_increment: " << sample_increment << endl;
1575 cout << "sample: " << sample1 << " -> ";
1576 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1585 AudioClock::minsec_frame_from_display () const
1591 int hrs = atoi (ms_hours_label.get_text());
1592 int mins = atoi (ms_minutes_label.get_text());
1593 float secs = atof (ms_seconds_label.get_text());
1595 jack_nframes_t sr = session->frame_rate();
1597 return (jack_nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1601 AudioClock::bbt_frame_from_display (jack_nframes_t pos) const
1604 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1609 any.type = AnyTime::BBT;
1611 any.bbt.bars = atoi (bars_label.get_text());
1612 any.bbt.beats = atoi (beats_label.get_text());
1613 any.bbt.ticks = atoi (ticks_label.get_text());
1615 jack_nframes_t ret = session->convert_to_frames_at (pos, any);
1622 AudioClock::bbt_frame_duration_from_display (jack_nframes_t pos) const
1625 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1632 bbt.bars = atoi (bars_label.get_text());
1633 bbt.beats = atoi (beats_label.get_text());
1634 bbt.ticks = atoi (ticks_label.get_text());
1636 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1640 AudioClock::audio_frame_from_display () const
1642 return (jack_nframes_t) atoi (audio_frames_label.get_text());
1646 AudioClock::build_ops_menu ()
1648 using namespace Menu_Helpers;
1649 ops_menu = new Menu;
1650 MenuList& ops_items = ops_menu->items();
1651 ops_menu->set_name ("ArdourContextMenu");
1653 Menu *mode_menu = manage (new Menu);
1654 MenuList& mode_items = mode_menu->items();
1655 mode_menu->set_name ("ArdourContextMenu");
1657 mode_items.push_back (MenuElem (_("SMPTE"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1658 mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1659 mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1660 mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1661 mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1663 ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1667 AudioClock::set_mode (Mode m)
1669 /* slightly tricky: this is called from within the ARDOUR_UI
1670 constructor by some of its clock members. at that time
1671 the instance pointer is unset, so we have to be careful.
1672 the main idea is to drop keyboard focus in case we had
1673 started editing the clock and then we switch clock mode.
1676 // GTK2FIX might need an equivalent here for drop focus
1687 clock_base.remove ();
1697 clock_base.add (smpte_packer_hbox);
1698 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 0, 2);
1699 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 0, 2);
1700 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 0, 2);
1701 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 0, 2);
1705 clock_base.add (bbt_packer_hbox);
1706 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 0, 2);
1707 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 0, 2);
1708 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 0, 2);
1712 clock_base.add (minsec_packer_hbox);
1713 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "99", 0, 2);
1714 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "99", 0, 2);
1715 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "99", 0, 2);
1719 clock_base.add (frames_packer_hbox);
1720 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 0, 2);
1726 set (last_when, true);
1727 clock_base.show_all ();
1728 key_entry_state = 0;