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
24 #include <pbd/convert.h>
26 #include <gtkmm2ext/utils.h>
28 #include <ardour/ardour.h>
29 #include <ardour/session.h>
30 #include <ardour/tempo.h>
31 #include <sigc++/bind.h>
33 #include "ardour_ui.h"
34 #include "audio_clock.h"
39 using namespace ARDOUR;
47 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
49 2, /* SMPTE_Minutes */
50 2, /* SMPTE_Seconds */
61 AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool with_extras)
62 : is_duration (duration),
63 editable (allow_edit),
78 audio_frames_ebox.add (audio_frames_label);
79 frames_packer_hbox.set_border_width (2);
80 frames_packer_hbox.pack_start (audio_frames_ebox, false, false);
82 hours_ebox.add (hours_label);
83 minutes_ebox.add (minutes_label);
84 seconds_ebox.add (seconds_label);
85 frames_ebox.add (frames_label);
86 bars_ebox.add (bars_label);
87 beats_ebox.add (beats_label);
88 ticks_ebox.add (ticks_label);
89 ms_hours_ebox.add (ms_hours_label);
90 ms_minutes_ebox.add (ms_minutes_label);
91 ms_seconds_ebox.add (ms_seconds_label);
93 smpte_packer.set_homogeneous (false);
94 smpte_packer.set_border_width (2);
95 smpte_packer.pack_start (hours_ebox, false, false);
96 smpte_packer.pack_start (colon1, false, false);
97 smpte_packer.pack_start (minutes_ebox, false, false);
98 smpte_packer.pack_start (colon2, false, false);
99 smpte_packer.pack_start (seconds_ebox, false, false);
100 smpte_packer.pack_start (colon3, false, false);
101 smpte_packer.pack_start (frames_ebox, false, false);
103 smpte_packer_hbox.pack_start (smpte_packer, true, false);
105 bbt_packer.set_homogeneous (false);
106 bbt_packer.set_border_width (2);
107 bbt_packer.pack_start (bars_ebox, false, false);
108 bbt_packer.pack_start (b1, false, false);
109 bbt_packer.pack_start (beats_ebox, false, false);
110 bbt_packer.pack_start (b2, false, false);
111 bbt_packer.pack_start (ticks_ebox, false, false);
115 framerate_label = manage (new Label);
116 pullup_label = manage (new Label);
118 framerate_label->set_name ("BBTMeterLabel");
119 pullup_label->set_name ("BBTTempoLabel");
121 rate_pullup_box.pack_start (*framerate_label, true, true);
122 rate_pullup_box.pack_start (*pullup_label, true, true);
124 smpte_packer.pack_start (rate_pullup_box, false,false, 5);
126 meter_label = manage (new Label);
127 tempo_label = manage (new Label);
129 meter_label->set_name ("BBTMeterLabel");
130 tempo_label->set_name ("BBTTempoLabel");
132 tempo_meter_box.pack_start (*meter_label, true, true);
133 tempo_meter_box.pack_start (*tempo_label, true, true);
135 bbt_packer.pack_start (tempo_meter_box, false, false, 5);
143 bbt_packer_hbox.pack_start (bbt_packer, true, false);
145 minsec_packer.set_homogeneous (false);
146 minsec_packer.set_border_width (2);
147 minsec_packer.pack_start (ms_hours_ebox, false, false);
148 minsec_packer.pack_start (colon4, false, false);
149 minsec_packer.pack_start (ms_minutes_ebox, false, false);
150 minsec_packer.pack_start (colon5, false, false);
151 minsec_packer.pack_start (ms_seconds_ebox, false, false);
153 minsec_packer_hbox.pack_start (minsec_packer, true, false);
156 clock_base.set_name (name);
158 audio_frames_label.set_name (name);
159 hours_label.set_name (name);
160 minutes_label.set_name (name);
161 seconds_label.set_name (name);
162 frames_label.set_name (name);
163 bars_label.set_name (name);
164 beats_label.set_name (name);
165 ticks_label.set_name (name);
166 ms_hours_label.set_name (name);
167 ms_minutes_label.set_name (name);
168 ms_seconds_label.set_name (name);
169 hours_ebox.set_name (name);
170 minutes_ebox.set_name (name);
171 seconds_ebox.set_name (name);
172 frames_ebox.set_name (name);
173 audio_frames_ebox.set_name (name);
174 bars_ebox.set_name (name);
175 beats_ebox.set_name (name);
176 ticks_ebox.set_name (name);
177 ms_hours_ebox.set_name (name);
178 ms_minutes_ebox.set_name (name);
179 ms_seconds_ebox.set_name (name);
181 colon1.set_name (name);
182 colon2.set_name (name);
183 colon3.set_name (name);
184 colon4.set_name (name);
185 colon5.set_name (name);
189 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
190 clock_frame.set_name ("BaseFrame");
192 clock_frame.add (clock_base);
194 _mode = BBT; /* lie to force mode switch */
197 pack_start (clock_frame, true, true);
199 /* the clock base handles button releases for menu popup regardless of
200 editable status. if the clock is editable, the clock base is where
201 we pass focus to after leaving the last editable "field", which
202 will then shutdown editing till the user starts it up again.
204 it does this because the focus out event on the field disables
205 keyboard event handling, and we don't connect anything up to
206 notice focus in on the clock base. hence, keyboard event handling
210 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
211 clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
213 Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
219 set (last_when, true);
223 AudioClock::setup_events ()
225 clock_base.set_flags (Gtk::CAN_FOCUS);
227 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|Gdk::SCROLL_MASK);
228 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|Gdk::SCROLL_MASK);
229 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|Gdk::SCROLL_MASK);
230 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|Gdk::SCROLL_MASK);
231 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|Gdk::SCROLL_MASK);
232 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|Gdk::SCROLL_MASK);
233 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|Gdk::SCROLL_MASK);
234 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|Gdk::SCROLL_MASK);
235 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|Gdk::SCROLL_MASK);
236 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|Gdk::SCROLL_MASK);
237 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|Gdk::SCROLL_MASK);
239 hours_ebox.set_flags (Gtk::CAN_FOCUS);
240 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
241 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
242 frames_ebox.set_flags (Gtk::CAN_FOCUS);
243 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
244 bars_ebox.set_flags (Gtk::CAN_FOCUS);
245 beats_ebox.set_flags (Gtk::CAN_FOCUS);
246 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
247 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
248 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
249 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
251 hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
252 minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
253 seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
254 frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
255 audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
256 bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
257 beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
258 ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
259 ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
260 ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
261 ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
263 hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Hours));
264 minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
265 seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
266 frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Frames));
267 audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
268 bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
269 beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
270 ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
271 ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
272 ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
273 ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
275 hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Hours));
276 minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
277 seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
278 frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Frames));
279 audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
280 bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
281 beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
282 ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
283 ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
284 ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
285 ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
287 hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Hours));
288 minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Minutes));
289 seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Seconds));
290 frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Frames));
291 audio_frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
292 bars_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
293 beats_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
294 ticks_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
295 ms_hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
296 ms_minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
297 ms_seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
299 hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours));
300 minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
301 seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
302 frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Frames));
303 audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
304 bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
305 beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
306 ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
307 ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
308 ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
309 ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
311 hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
312 minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
313 seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
314 frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
315 audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
316 bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
317 beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
318 ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
319 ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
320 ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
321 ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
323 hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
324 minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
325 seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
326 frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
327 audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
328 bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
329 beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
330 ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
331 ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
332 ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
333 ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
337 AudioClock::on_realize ()
341 /* styles are not available until the widgets are bound to a window */
343 set_size_requests ();
347 AudioClock::set (nframes_t when, bool force)
350 if ((!force && !is_visible()) || session == 0) {
354 if (when == last_when && !force) {
360 set_smpte (when, force);
364 set_bbt (when, force);
368 set_minsec (when, force);
372 set_frames (when, force);
383 AudioClock::smpte_offset_changed ()
390 current = current_duration();
392 current = current_time ();
402 AudioClock::set_frames (nframes_t when, bool force)
405 snprintf (buf, sizeof (buf), "%u", when);
406 audio_frames_label.set_text (buf);
410 AudioClock::set_minsec (nframes_t when, bool force)
419 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
420 left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
421 mins = (int) floor (left / (session->frame_rate() * 60.0f));
422 left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
423 secs = left / (float) session->frame_rate();
425 if (force || hrs != ms_last_hrs) {
426 sprintf (buf, "%02d", hrs);
427 ms_hours_label.set_text (buf);
431 if (force || mins != ms_last_mins) {
432 sprintf (buf, "%02d", mins);
433 ms_minutes_label.set_text (buf);
437 if (force || secs != ms_last_secs) {
438 sprintf (buf, "%06.3f", secs);
439 ms_seconds_label.set_text (buf);
445 AudioClock::set_smpte (nframes_t when, bool force)
451 session->smpte_duration (when, smpte);
453 session->smpte_time (when, smpte);
456 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
457 if (smpte.negative) {
458 sprintf (buf, "-%02" PRIu32, smpte.hours);
460 sprintf (buf, " %02" PRIu32, smpte.hours);
462 hours_label.set_text (buf);
463 last_hrs = smpte.hours;
464 last_negative = smpte.negative;
467 if (force || smpte.minutes != last_mins) {
468 sprintf (buf, "%02" PRIu32, smpte.minutes);
469 minutes_label.set_text (buf);
470 last_mins = smpte.minutes;
473 if (force || smpte.seconds != last_secs) {
474 sprintf (buf, "%02" PRIu32, smpte.seconds);
475 seconds_label.set_text (buf);
476 last_secs = smpte.seconds;
479 if (force || smpte.frames != last_frames) {
480 sprintf (buf, "%02" PRIu32, smpte.frames);
481 frames_label.set_text (buf);
482 last_frames = smpte.frames;
485 if (framerate_label) {
486 sprintf (buf, "%-5.2f", Config->get_smpte_frames_per_second());
487 framerate_label->set_text (buf);
489 float x = Config->get_video_pullup();
492 pullup_label->set_text (_("none"));
494 sprintf (buf, "%-6.4f", x);
495 pullup_label->set_text (buf);
501 AudioClock::set_bbt (nframes_t when, bool force)
506 session->tempo_map().bbt_time (when, bbt);
507 sprintf (buf, "%03" PRIu32, bbt.bars);
508 bars_label.set_text (buf);
509 sprintf (buf, "%02" PRIu32, bbt.beats);
510 beats_label.set_text (buf);
511 sprintf (buf, "%04" PRIu32, bbt.ticks);
512 ticks_label.set_text (buf);
515 TempoMap::Metric m (session->tempo_map().metric_at (when));
516 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
517 tempo_label->set_text (buf);
518 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
519 meter_label->set_text (buf);
524 AudioClock::set_session (Session *s)
529 set (last_when, true);
534 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
539 bool move_on = false;
543 label = &hours_label;
546 label = &minutes_label;
549 label = &seconds_label;
552 label = &frames_label;
556 label = &audio_frames_label;
560 label = &ms_hours_label;
563 label = &ms_minutes_label;
566 label = &ms_seconds_label;
573 label = &beats_label;
576 label = &ticks_label;
582 switch (ev->keyval) {
626 if (_mode == MinSec && field == MS_Seconds) {
640 clock_base.grab_focus ();
649 if (key_entry_state == 0) {
651 /* initialize with a fresh new string */
653 if (field != AudioFrames) {
654 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
663 string existing = label->get_text();
664 if (existing.length() >= field_length[field]) {
665 new_text = existing.substr (1, field_length[field] - 1);
667 new_text = existing.substr (0, field_length[field] - 1);
671 new_text += new_char;
672 label->set_text (new_text);
676 if (key_entry_state == field_length[field]) {
682 if (key_entry_state) {
689 // Check SMPTE fields for sanity (may also adjust fields)
690 smpte_sanitize_display();
696 ValueChanged(); /* EMIT_SIGNAL */
699 /* move on to the next field.
707 minutes_ebox.grab_focus ();
710 seconds_ebox.grab_focus ();
713 frames_ebox.grab_focus ();
716 clock_base.grab_focus ();
721 clock_base.grab_focus ();
727 ms_minutes_ebox.grab_focus ();
730 ms_seconds_ebox.grab_focus ();
733 clock_base.grab_focus ();
739 beats_ebox.grab_focus ();
742 ticks_ebox.grab_focus ();
745 clock_base.grab_focus ();
758 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
764 hours_ebox.set_flags (Gtk::HAS_FOCUS);
765 hours_ebox.set_state (Gtk::STATE_ACTIVE);
768 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
769 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
772 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
773 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
776 frames_ebox.set_flags (Gtk::HAS_FOCUS);
777 frames_ebox.set_state (Gtk::STATE_ACTIVE);
781 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
782 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
786 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
787 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
790 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
791 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
794 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
795 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
798 bars_ebox.set_flags (Gtk::HAS_FOCUS);
799 bars_ebox.set_state (Gtk::STATE_ACTIVE);
802 beats_ebox.set_flags (Gtk::HAS_FOCUS);
803 beats_ebox.set_state (Gtk::STATE_ACTIVE);
806 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
807 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
815 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
820 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
821 hours_ebox.set_state (Gtk::STATE_NORMAL);
824 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
825 minutes_ebox.set_state (Gtk::STATE_NORMAL);
828 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
829 seconds_ebox.set_state (Gtk::STATE_NORMAL);
832 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
833 frames_ebox.set_state (Gtk::STATE_NORMAL);
837 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
838 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
842 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
843 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
846 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
847 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
850 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
851 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
855 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
856 bars_ebox.set_state (Gtk::STATE_NORMAL);
859 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
860 beats_ebox.set_state (Gtk::STATE_NORMAL);
863 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
864 ticks_ebox.set_state (Gtk::STATE_NORMAL);
872 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
877 gdk_pointer_ungrab(GDK_CURRENT_TIME);
879 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
880 // we actually dragged so return without setting editing focus, or we shift clicked
890 ops_menu->popup (1, ev->time);
894 if (Keyboard::is_context_menu_event (ev)) {
898 ops_menu->popup (1, ev->time);
902 switch (ev->button) {
906 hours_ebox.grab_focus();
909 minutes_ebox.grab_focus();
912 seconds_ebox.grab_focus();
915 frames_ebox.grab_focus();
919 audio_frames_ebox.grab_focus();
923 ms_hours_ebox.grab_focus();
926 ms_minutes_ebox.grab_focus();
929 ms_seconds_ebox.grab_focus();
933 bars_ebox.grab_focus ();
936 beats_ebox.grab_focus ();
939 ticks_ebox.grab_focus ();
952 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
954 if (session == 0) return FALSE;
956 nframes_t frames = 0;
958 switch (ev->button) {
960 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
962 ValueChanged (); /* EMIT_SIGNAL */
965 /* make absolutely sure that the pointer is grabbed */
966 gdk_pointer_grab(ev->window,FALSE ,
967 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
971 drag_start_y = ev->y;
976 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
978 ValueChanged (); /* EMIT_SIGNAL */
983 /* used for context sensitive menu */
988 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
989 frames = get_frames (field);
991 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
994 set (current_time() + frames, true);
995 ValueChanged (); /* EMIT_SIGNAL */
1001 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1002 frames = get_frames (field);
1004 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1008 if ((double)current_time() - (double)frames < 0.0) {
1012 set (current_time() - frames, true);
1015 ValueChanged (); /* EMIT_SIGNAL */
1029 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1031 if (session == 0) return FALSE;
1033 nframes_t frames = 0;
1035 switch (ev->direction) {
1038 frames = get_frames (field);
1040 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1043 set (current_time() + frames, true);
1044 ValueChanged (); /* EMIT_SIGNAL */
1048 case GDK_SCROLL_DOWN:
1049 frames = get_frames (field);
1051 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1055 if ((double)current_time() - (double)frames < 0.0) {
1058 set (current_time() - frames, true);
1061 ValueChanged (); /* EMIT_SIGNAL */
1074 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1076 if (session == 0 || !dragging) {
1080 float pixel_frame_scale_factor = 0.2f;
1083 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1084 pixel_frame_scale_factor = 0.1f;
1088 if (Keyboard::modifier_state_contains (ev->state,
1089 Keyboard::Control|Keyboard::Alt)) {
1091 pixel_frame_scale_factor = 0.025f;
1094 double y_delta = ev->y - drag_y;
1096 drag_accum += y_delta*pixel_frame_scale_factor;
1100 if (trunc(drag_accum) != 0) {
1105 dir = (drag_accum < 0 ? 1:-1);
1106 pos = current_time();
1107 frames = get_frames (field,pos,dir);
1109 if (frames != 0 && frames * drag_accum < current_time()) {
1111 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1119 ValueChanged(); /* EMIT_SIGNAL */
1128 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1131 nframes_t frames = 0;
1135 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1138 frames = (nframes_t) floor (60.0 * session->frame_rate());
1141 frames = session->frame_rate();
1144 frames = (nframes_t) floor (session->frame_rate() / Config->get_smpte_frames_per_second());
1152 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1155 frames = (nframes_t) floor (60.0 * session->frame_rate());
1158 frames = session->frame_rate();
1165 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1171 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1177 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1185 AudioClock::current_time (nframes_t pos) const
1191 ret = smpte_frame_from_display ();
1194 ret = bbt_frame_from_display (pos);
1198 ret = minsec_frame_from_display ();
1202 ret = audio_frame_from_display ();
1213 AudioClock::current_duration (nframes_t pos) const
1219 ret = smpte_frame_from_display ();
1222 ret = bbt_frame_duration_from_display (pos);
1226 ret = minsec_frame_from_display ();
1230 ret = audio_frame_from_display ();
1241 AudioClock::smpte_sanitize_display()
1243 // Check SMPTE fields for sanity, possibly adjusting values
1244 if (atoi(minutes_label.get_text()) > 59) {
1245 minutes_label.set_text("59");
1248 if (atoi(seconds_label.get_text()) > 59) {
1249 seconds_label.set_text("59");
1252 switch ((long)rint(Config->get_smpte_frames_per_second())) {
1254 if (atoi(frames_label.get_text()) > 23) {
1255 frames_label.set_text("23");
1259 if (atoi(frames_label.get_text()) > 24) {
1260 frames_label.set_text("24");
1264 if (atoi(frames_label.get_text()) > 29) {
1265 frames_label.set_text("29");
1272 if (Config->get_smpte_drop_frames()) {
1273 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1274 frames_label.set_text("02");
1280 AudioClock::smpte_frame_from_display () const
1289 smpte.hours = atoi (hours_label.get_text());
1290 smpte.minutes = atoi (minutes_label.get_text());
1291 smpte.seconds = atoi (seconds_label.get_text());
1292 smpte.frames = atoi (frames_label.get_text());
1294 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1298 #define SMPTE_SAMPLE_TEST_1
1299 #define SMPTE_SAMPLE_TEST_2
1300 #define SMPTE_SAMPLE_TEST_3
1301 #define SMPTE_SAMPLE_TEST_4
1302 #define SMPTE_SAMPLE_TEST_5
1303 #define SMPTE_SAMPLE_TEST_6
1304 #define SMPTE_SAMPLE_TEST_7
1306 // Testcode for smpte<->sample conversions (P.S.)
1309 nframes_t oldsample = 0;
1311 nframes_t sample_increment;
1313 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1315 #ifdef SMPTE_SAMPLE_TEST_1
1316 // Test 1: use_offset = false, use_subframes = false
1317 cout << "use_offset = false, use_subframes = false" << endl;
1318 for (int i = 0; i < 108003; i++) {
1319 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1320 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1322 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1323 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1324 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1325 cout << "sample: " << sample1 << endl;
1326 cout << "sample: " << sample1 << " -> ";
1327 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1331 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1332 cout << "ERROR: smpte2 not equal smpte1" << endl;
1333 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1334 cout << "sample: " << sample1 << endl;
1335 cout << "sample: " << sample1 << " -> ";
1336 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1339 oldsample = sample1;
1340 session->smpte_increment( smpte1 );
1343 cout << "sample_increment: " << sample_increment << endl;
1344 cout << "sample: " << sample1 << " -> ";
1345 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1348 #ifdef SMPTE_SAMPLE_TEST_2
1349 // Test 2: use_offset = true, use_subframes = false
1350 cout << "use_offset = true, use_subframes = false" << endl;
1356 smpte1.subframes = 0;
1357 sample1 = oldsample = 0;
1359 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1360 cout << "Starting at sample: " << sample1 << " -> ";
1361 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1363 for (int i = 0; i < 108003; i++) {
1364 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1365 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1367 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1368 // cout << "sample: " << sample1 << endl;
1369 // cout << "sample: " << sample1 << " -> ";
1370 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1372 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1373 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1374 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1375 cout << "sample: " << sample1 << endl;
1376 cout << "sample: " << sample1 << " -> ";
1377 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1381 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1382 cout << "ERROR: smpte2 not equal smpte1" << endl;
1383 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1384 cout << "sample: " << sample1 << endl;
1385 cout << "sample: " << sample1 << " -> ";
1386 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1389 oldsample = sample1;
1390 session->smpte_increment( smpte1 );
1393 cout << "sample_increment: " << sample_increment << endl;
1394 cout << "sample: " << sample1 << " -> ";
1395 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1398 #ifdef SMPTE_SAMPLE_TEST_3
1399 // Test 3: use_offset = true, use_subframes = false, decrement
1400 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1402 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1403 cout << "Starting at sample: " << sample1 << " -> ";
1404 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1406 for (int i = 0; i < 108003; i++) {
1407 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1408 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1410 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1411 // cout << "sample: " << sample1 << endl;
1412 // cout << "sample: " << sample1 << " -> ";
1413 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1415 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1416 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << 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;
1424 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1425 cout << "ERROR: smpte2 not equal smpte1" << endl;
1426 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1427 cout << "sample: " << sample1 << endl;
1428 cout << "sample: " << sample1 << " -> ";
1429 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1432 oldsample = sample1;
1433 session->smpte_decrement( smpte1 );
1436 cout << "sample_decrement: " << sample_increment << endl;
1437 cout << "sample: " << sample1 << " -> ";
1438 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1442 #ifdef SMPTE_SAMPLE_TEST_4
1443 // Test 4: use_offset = true, use_subframes = true
1444 cout << "use_offset = true, use_subframes = true" << endl;
1446 for (long sub = 5; sub < 80; sub += 5) {
1451 smpte1.subframes = 0;
1452 sample1 = oldsample = (sample_increment * sub) / 80;
1454 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1456 cout << "starting at sample: " << sample1 << " -> ";
1457 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1459 for (int i = 0; i < 108003; i++) {
1460 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1461 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1463 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1464 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1465 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1466 cout << "sample: " << sample1 << endl;
1467 cout << "sample: " << sample1 << " -> ";
1468 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1472 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1473 cout << "ERROR: smpte2 not equal smpte1" << endl;
1474 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1475 cout << "sample: " << sample1 << endl;
1476 cout << "sample: " << sample1 << " -> ";
1477 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1480 oldsample = sample1;
1481 session->smpte_increment( smpte1 );
1484 cout << "sample_increment: " << sample_increment << endl;
1485 cout << "sample: " << sample1 << " -> ";
1486 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1488 for (int i = 0; i < 108003; i++) {
1489 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1490 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1492 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1493 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1494 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1495 cout << "sample: " << sample1 << endl;
1496 cout << "sample: " << sample1 << " -> ";
1497 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1501 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1502 cout << "ERROR: smpte2 not equal smpte1" << endl;
1503 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1504 cout << "sample: " << sample1 << endl;
1505 cout << "sample: " << sample1 << " -> ";
1506 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1509 oldsample = sample1;
1510 session->smpte_decrement( smpte1 );
1513 cout << "sample_decrement: " << sample_increment << endl;
1514 cout << "sample: " << sample1 << " -> ";
1515 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1520 #ifdef SMPTE_SAMPLE_TEST_5
1521 // Test 5: use_offset = true, use_subframes = false, increment seconds
1522 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1528 smpte1.subframes = 0;
1529 sample1 = oldsample = 0;
1530 sample_increment = session->frame_rate();
1532 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1533 cout << "Starting at sample: " << sample1 << " -> ";
1534 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1536 for (int i = 0; i < 3600; i++) {
1537 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1538 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1540 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1541 // cout << "sample: " << sample1 << endl;
1542 // cout << "sample: " << sample1 << " -> ";
1543 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1545 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1547 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1551 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1552 cout << "ERROR: smpte2 not equal smpte1" << endl;
1553 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1554 cout << "sample: " << sample1 << endl;
1555 cout << "sample: " << sample1 << " -> ";
1556 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1559 oldsample = sample1;
1560 session->smpte_increment_seconds( smpte1 );
1563 cout << "sample_increment: " << sample_increment << endl;
1564 cout << "sample: " << sample1 << " -> ";
1565 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1569 #ifdef SMPTE_SAMPLE_TEST_6
1570 // Test 6: use_offset = true, use_subframes = false, increment minutes
1571 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1577 smpte1.subframes = 0;
1578 sample1 = oldsample = 0;
1579 sample_increment = session->frame_rate() * 60;
1581 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1582 cout << "Starting at sample: " << sample1 << " -> ";
1583 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1585 for (int i = 0; i < 60; i++) {
1586 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1587 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1589 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1590 // cout << "sample: " << sample1 << endl;
1591 // cout << "sample: " << sample1 << " -> ";
1592 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1594 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1596 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1600 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1601 cout << "ERROR: smpte2 not equal smpte1" << endl;
1602 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1603 cout << "sample: " << sample1 << endl;
1604 cout << "sample: " << sample1 << " -> ";
1605 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1608 oldsample = sample1;
1609 session->smpte_increment_minutes( smpte1 );
1612 cout << "sample_increment: " << sample_increment << endl;
1613 cout << "sample: " << sample1 << " -> ";
1614 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1617 #ifdef SMPTE_SAMPLE_TEST_7
1618 // Test 7: use_offset = true, use_subframes = false, increment hours
1619 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1625 smpte1.subframes = 0;
1626 sample1 = oldsample = 0;
1627 sample_increment = session->frame_rate() * 60 * 60;
1629 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1630 cout << "Starting at sample: " << sample1 << " -> ";
1631 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1633 for (int i = 0; i < 10; i++) {
1634 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1635 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1637 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1638 // cout << "sample: " << sample1 << endl;
1639 // cout << "sample: " << sample1 << " -> ";
1640 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1642 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1644 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1648 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1649 cout << "ERROR: smpte2 not equal smpte1" << endl;
1650 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1651 cout << "sample: " << sample1 << endl;
1652 cout << "sample: " << sample1 << " -> ";
1653 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1656 oldsample = sample1;
1657 session->smpte_increment_hours( smpte1 );
1660 cout << "sample_increment: " << sample_increment << endl;
1661 cout << "sample: " << sample1 << " -> ";
1662 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1671 AudioClock::minsec_frame_from_display () const
1677 int hrs = atoi (ms_hours_label.get_text());
1678 int mins = atoi (ms_minutes_label.get_text());
1679 float secs = atof (ms_seconds_label.get_text());
1681 nframes_t sr = session->frame_rate();
1683 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1687 AudioClock::bbt_frame_from_display (nframes_t pos) const
1690 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1695 any.type = AnyTime::BBT;
1697 any.bbt.bars = atoi (bars_label.get_text());
1698 any.bbt.beats = atoi (beats_label.get_text());
1699 any.bbt.ticks = atoi (ticks_label.get_text());
1701 nframes_t ret = session->convert_to_frames_at (pos, any);
1708 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1711 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1718 bbt.bars = atoi (bars_label.get_text());
1719 bbt.beats = atoi (beats_label.get_text());
1720 bbt.ticks = atoi (ticks_label.get_text());
1722 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1726 AudioClock::audio_frame_from_display () const
1728 return (nframes_t) atoi (audio_frames_label.get_text());
1732 AudioClock::build_ops_menu ()
1734 using namespace Menu_Helpers;
1735 ops_menu = new Menu;
1736 MenuList& ops_items = ops_menu->items();
1737 ops_menu->set_name ("ArdourContextMenu");
1739 Menu *mode_menu = manage (new Menu);
1740 MenuList& mode_items = mode_menu->items();
1741 mode_menu->set_name ("ArdourContextMenu");
1743 mode_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1744 mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1745 mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1746 mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1747 mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1749 ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1753 AudioClock::set_mode (Mode m)
1755 /* slightly tricky: this is called from within the ARDOUR_UI
1756 constructor by some of its clock members. at that time
1757 the instance pointer is unset, so we have to be careful.
1758 the main idea is to drop keyboard focus in case we had
1759 started editing the clock and then we switch clock mode.
1762 clock_base.grab_focus ();
1772 clock_base.remove ();
1782 clock_base.add (smpte_packer_hbox);
1786 clock_base.add (bbt_packer_hbox);
1790 clock_base.add (minsec_packer_hbox);
1794 clock_base.add (frames_packer_hbox);
1801 set_size_requests ();
1803 set (last_when, true);
1804 clock_base.show_all ();
1805 key_entry_state = 0;
1809 AudioClock::set_size_requests ()
1811 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
1815 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 2, 2);
1816 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 2, 2);
1817 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 2, 2);
1818 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 2, 2);
1822 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 2, 2);
1823 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 2, 2);
1824 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 2, 2);
1828 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "99", 2, 2);
1829 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "99", 2, 2);
1830 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "99.999", 2, 2);
1834 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 2, 2);