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.
20 #include <cstdio> // for sprintf
23 #include <pbd/convert.h>
24 #include <pbd/enumwriter.h>
26 #include <gtkmm2ext/utils.h>
28 #include <ardour/ardour.h>
29 #include <ardour/session.h>
30 #include <ardour/tempo.h>
31 #include <ardour/profile.h>
32 #include <sigc++/bind.h>
34 #include "ardour_ui.h"
35 #include "audio_clock.h"
40 using namespace ARDOUR;
49 sigc::signal<void> AudioClock::ModeChanged;
50 vector<AudioClock*> AudioClock::clocks;
52 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
54 2, /* SMPTE_Minutes */
55 2, /* SMPTE_Seconds */
66 AudioClock::AudioClock (std::string clock_name, bool transient, std::string widget_name, bool allow_edit, bool duration, bool with_info)
68 is_transient (transient),
69 is_duration (duration),
70 editable (allow_edit),
88 frames_upper_info_label = manage (new Label);
89 frames_lower_info_label = manage (new Label);
90 smpte_upper_info_label = manage (new Label);
91 smpte_lower_info_label = manage (new Label);
92 bbt_upper_info_label = manage (new Label);
93 bbt_lower_info_label = manage (new Label);
95 frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
96 frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
97 smpte_upper_info_label->set_name ("AudioClockSMPTEUpperInfo");
98 smpte_lower_info_label->set_name ("AudioClockSMPTELowerInfo");
99 bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
100 bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
102 Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0);
103 Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0);
105 frames_info_box.pack_start (*frames_upper_info_label, true, true);
106 frames_info_box.pack_start (*frames_lower_info_label, true, true);
107 smpte_info_box.pack_start (*smpte_upper_info_label, true, true);
108 smpte_info_box.pack_start (*smpte_lower_info_label, true, true);
109 bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
110 bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
113 frames_upper_info_label = 0;
114 frames_lower_info_label = 0;
115 smpte_upper_info_label = 0;
116 smpte_lower_info_label = 0;
117 bbt_upper_info_label = 0;
118 bbt_lower_info_label = 0;
121 audio_frames_ebox.add (audio_frames_label);
123 frames_packer.set_homogeneous (false);
124 frames_packer.set_border_width (2);
125 frames_packer.pack_start (audio_frames_ebox, false, false);
128 frames_packer.pack_start (frames_info_box, false, false, 5);
131 frames_packer_hbox.pack_start (frames_packer, true, false);
133 hours_ebox.add (hours_label);
134 minutes_ebox.add (minutes_label);
135 seconds_ebox.add (seconds_label);
136 frames_ebox.add (frames_label);
137 bars_ebox.add (bars_label);
138 beats_ebox.add (beats_label);
139 ticks_ebox.add (ticks_label);
140 ms_hours_ebox.add (ms_hours_label);
141 ms_minutes_ebox.add (ms_minutes_label);
142 ms_seconds_ebox.add (ms_seconds_label);
144 smpte_packer.set_homogeneous (false);
145 smpte_packer.set_border_width (2);
146 smpte_packer.pack_start (hours_ebox, false, false);
147 smpte_packer.pack_start (colon1, false, false);
148 smpte_packer.pack_start (minutes_ebox, false, false);
149 smpte_packer.pack_start (colon2, false, false);
150 smpte_packer.pack_start (seconds_ebox, false, false);
151 smpte_packer.pack_start (colon3, false, false);
152 smpte_packer.pack_start (frames_ebox, false, false);
155 smpte_packer.pack_start (smpte_info_box, false, false, 5);
158 smpte_packer_hbox.pack_start (smpte_packer, true, false);
160 bbt_packer.set_homogeneous (false);
161 bbt_packer.set_border_width (2);
162 bbt_packer.pack_start (bars_ebox, false, false);
163 bbt_packer.pack_start (b1, false, false);
164 bbt_packer.pack_start (beats_ebox, false, false);
165 bbt_packer.pack_start (b2, false, false);
166 bbt_packer.pack_start (ticks_ebox, false, false);
169 bbt_packer.pack_start (bbt_info_box, false, false, 5);
172 bbt_packer_hbox.pack_start (bbt_packer, true, false);
174 minsec_packer.set_homogeneous (false);
175 minsec_packer.set_border_width (2);
176 minsec_packer.pack_start (ms_hours_ebox, false, false);
177 minsec_packer.pack_start (colon4, false, false);
178 minsec_packer.pack_start (ms_minutes_ebox, false, false);
179 minsec_packer.pack_start (colon5, false, false);
180 minsec_packer.pack_start (ms_seconds_ebox, false, false);
182 minsec_packer_hbox.pack_start (minsec_packer, true, false);
184 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
185 clock_frame.set_name ("BaseFrame");
187 clock_frame.add (clock_base);
189 set_widget_name (widget_name);
191 _mode = BBT; /* lie to force mode switch */
194 pack_start (clock_frame, true, true);
196 /* the clock base handles button releases for menu popup regardless of
197 editable status. if the clock is editable, the clock base is where
198 we pass focus to after leaving the last editable "field", which
199 will then shutdown editing till the user starts it up again.
201 it does this because the focus out event on the field disables
202 keyboard event handling, and we don't connect anything up to
203 notice focus in on the clock base. hence, keyboard event handling
207 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
208 clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
210 Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
216 set (last_when, true);
219 clocks.push_back (this);
224 AudioClock::set_widget_name (string name)
226 Widget::set_name (name);
228 clock_base.set_name (name);
230 audio_frames_label.set_name (name);
231 hours_label.set_name (name);
232 minutes_label.set_name (name);
233 seconds_label.set_name (name);
234 frames_label.set_name (name);
235 bars_label.set_name (name);
236 beats_label.set_name (name);
237 ticks_label.set_name (name);
238 ms_hours_label.set_name (name);
239 ms_minutes_label.set_name (name);
240 ms_seconds_label.set_name (name);
241 hours_ebox.set_name (name);
242 minutes_ebox.set_name (name);
243 seconds_ebox.set_name (name);
244 frames_ebox.set_name (name);
245 audio_frames_ebox.set_name (name);
246 bars_ebox.set_name (name);
247 beats_ebox.set_name (name);
248 ticks_ebox.set_name (name);
249 ms_hours_ebox.set_name (name);
250 ms_minutes_ebox.set_name (name);
251 ms_seconds_ebox.set_name (name);
253 colon1.set_name (name);
254 colon2.set_name (name);
255 colon3.set_name (name);
256 colon4.set_name (name);
257 colon5.set_name (name);
265 AudioClock::setup_events ()
267 clock_base.set_flags (Gtk::CAN_FOCUS);
269 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);
270 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);
271 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);
272 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);
273 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);
274 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);
275 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);
276 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);
277 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);
278 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);
279 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);
281 hours_ebox.set_flags (Gtk::CAN_FOCUS);
282 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
283 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
284 frames_ebox.set_flags (Gtk::CAN_FOCUS);
285 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
286 bars_ebox.set_flags (Gtk::CAN_FOCUS);
287 beats_ebox.set_flags (Gtk::CAN_FOCUS);
288 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
289 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
290 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
291 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
293 hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
294 minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
295 seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
296 frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
297 audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
298 bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
299 beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
300 ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
301 ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
302 ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
303 ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
305 hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Hours));
306 minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
307 seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
308 frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Frames));
309 audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
310 bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
311 beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
312 ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
313 ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
314 ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
315 ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
317 hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Hours));
318 minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
319 seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
320 frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Frames));
321 audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
322 bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
323 beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
324 ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
325 ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
326 ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
327 ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
329 hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Hours));
330 minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Minutes));
331 seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Seconds));
332 frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Frames));
333 audio_frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
334 bars_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
335 beats_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
336 ticks_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
337 ms_hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
338 ms_minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
339 ms_seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
341 hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Hours));
342 minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Minutes));
343 seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Seconds));
344 frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Frames));
345 audio_frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), AudioFrames));
346 bars_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Bars));
347 beats_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Beats));
348 ticks_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Ticks));
349 ms_hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Hours));
350 ms_minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Minutes));
351 ms_seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Seconds));
353 hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours));
354 minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
355 seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
356 frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Frames));
357 audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
358 bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
359 beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
360 ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
361 ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
362 ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
363 ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
365 hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
366 minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
367 seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
368 frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
369 audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
370 bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
371 beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
372 ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
373 ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
374 ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
375 ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
377 hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
378 minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
379 seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
380 frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
381 audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
382 bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
383 beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
384 ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
385 ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
386 ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
387 ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
389 clock_base.signal_focus_in_event().connect (mem_fun (*this, &AudioClock::drop_focus_handler));
393 AudioClock::drop_focus_handler (GdkEventFocus* ignored)
395 Keyboard::magic_widget_drop_focus ();
400 AudioClock::on_realize ()
404 /* styles are not available until the widgets are bound to a window */
406 set_size_requests ();
410 AudioClock::set (nframes_t when, bool force, nframes_t offset, char which)
413 if ((!force && !is_visible()) || session == 0) {
417 if (when == last_when && !offset && !force) {
421 bool pdelta = Config->get_primary_clock_delta_edit_cursor();
422 bool sdelta = Config->get_secondary_clock_delta_edit_cursor();
424 if (offset && which == 'p' && pdelta) {
425 when = (when > offset) ? when - offset : offset - when;
426 } else if (offset && which == 's' && sdelta) {
427 when = (when > offset) ? when - offset : offset - when;
430 if (which == 'p' && pdelta && !last_pdelta) {
431 set_widget_name("TransportClockDisplayDelta");
433 } else if (which == 'p' && !pdelta && last_pdelta) {
434 set_widget_name("TransportClockDisplay");
436 } else if (which == 's' && sdelta && !last_sdelta) {
437 set_widget_name("SecondaryClockDisplayDelta");
439 } else if (which == 's' && !sdelta && last_sdelta) {
440 set_widget_name("SecondaryClockDisplay");
446 set_smpte (when, force);
450 set_bbt (when, force);
454 set_minsec (when, force);
458 set_frames (when, force);
469 AudioClock::smpte_offset_changed ()
476 current = current_duration();
478 current = current_time ();
488 AudioClock::set_frames (nframes_t when, bool force)
491 snprintf (buf, sizeof (buf), "%u", when);
492 audio_frames_label.set_text (buf);
494 if (frames_upper_info_label) {
495 nframes_t rate = session->frame_rate();
497 if (fmod (rate, 1000.0) == 0.000) {
498 sprintf (buf, "%uK", rate/1000);
500 sprintf (buf, "%.3fK", rate/1000.0f);
503 if (frames_upper_info_label->get_text() != buf) {
504 frames_upper_info_label->set_text (buf);
507 float vid_pullup = Config->get_video_pullup();
509 if (vid_pullup == 0.0) {
510 if (frames_lower_info_label->get_text () != _("none")) {
511 frames_lower_info_label->set_text(_("none"));
514 sprintf (buf, "%-6.4f", vid_pullup);
515 if (frames_lower_info_label->get_text() != buf) {
516 frames_lower_info_label->set_text (buf);
523 AudioClock::set_minsec (nframes_t when, bool force)
532 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
533 left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
534 mins = (int) floor (left / (session->frame_rate() * 60.0f));
535 left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
536 secs = left / (float) session->frame_rate();
538 if (force || hrs != ms_last_hrs) {
539 sprintf (buf, "%02d", hrs);
540 ms_hours_label.set_text (buf);
544 if (force || mins != ms_last_mins) {
545 sprintf (buf, "%02d", mins);
546 ms_minutes_label.set_text (buf);
550 if (force || secs != ms_last_secs) {
551 sprintf (buf, "%06.3f", secs);
552 ms_seconds_label.set_text (buf);
558 AudioClock::set_smpte (nframes_t when, bool force)
564 session->smpte_duration (when, smpte);
566 session->smpte_time (when, smpte);
569 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
570 if (smpte.negative) {
571 sprintf (buf, "-%02" PRIu32, smpte.hours);
573 sprintf (buf, " %02" PRIu32, smpte.hours);
575 hours_label.set_text (buf);
576 last_hrs = smpte.hours;
577 last_negative = smpte.negative;
580 if (force || smpte.minutes != last_mins) {
581 sprintf (buf, "%02" PRIu32, smpte.minutes);
582 minutes_label.set_text (buf);
583 last_mins = smpte.minutes;
586 if (force || smpte.seconds != last_secs) {
587 sprintf (buf, "%02" PRIu32, smpte.seconds);
588 seconds_label.set_text (buf);
589 last_secs = smpte.seconds;
592 if (force || smpte.frames != last_frames) {
593 sprintf (buf, "%02" PRIu32, smpte.frames);
594 frames_label.set_text (buf);
595 last_frames = smpte.frames;
598 if (smpte_upper_info_label) {
599 double smpte_frames = session->smpte_frames_per_second();
601 if ( fmod(smpte_frames, 1.0) == 0.0) {
602 sprintf (buf, "%u", int (smpte_frames));
604 sprintf (buf, "%.2f", smpte_frames);
607 if (smpte_upper_info_label->get_text() != buf) {
608 smpte_upper_info_label->set_text (buf);
611 if ((fabs(smpte_frames - 29.97) < 0.0001) || smpte_frames == 30) {
612 if (session->smpte_drop_frames()) {
615 sprintf (buf, "NDF");
618 // there is no drop frame alternative
622 if (smpte_lower_info_label->get_text() != buf) {
623 smpte_lower_info_label->set_text (buf);
629 AudioClock::set_bbt (nframes_t when, bool force)
634 session->tempo_map().bbt_time (when, bbt);
635 sprintf (buf, "%03" PRIu32, bbt.bars);
636 bars_label.set_text (buf);
637 sprintf (buf, "%02" PRIu32, bbt.beats);
638 beats_label.set_text (buf);
639 sprintf (buf, "%04" PRIu32, bbt.ticks);
640 ticks_label.set_text (buf);
642 if (bbt_upper_info_label) {
643 TempoMap::Metric m (session->tempo_map().metric_at (when));
644 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
645 if (bbt_lower_info_label->get_text() != buf) {
646 bbt_lower_info_label->set_text (buf);
648 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
649 if (bbt_upper_info_label->get_text() != buf) {
650 bbt_upper_info_label->set_text (buf);
656 AudioClock::set_session (Session *s)
663 XMLNode* node = session->extra_xml (X_("ClockModes"));
664 AudioClock::Mode amode;
667 if ((prop = node->property (_name)) != 0) {
668 amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
673 set (last_when, true);
682 hours_ebox.grab_focus ();
686 bars_ebox.grab_focus ();
690 ms_hours_ebox.grab_focus ();
694 frames_ebox.grab_focus ();
704 AudioClock::field_key_press_event (GdkEventKey *ev, Field field)
706 /* all key activity is handled on key release */
711 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
716 bool move_on = false;
720 label = &hours_label;
723 label = &minutes_label;
726 label = &seconds_label;
729 label = &frames_label;
733 label = &audio_frames_label;
737 label = &ms_hours_label;
740 label = &ms_minutes_label;
743 label = &ms_seconds_label;
750 label = &beats_label;
753 label = &ticks_label;
759 switch (ev->keyval) {
803 if (_mode == MinSec && field == MS_Seconds) {
817 clock_base.grab_focus ();
826 if (key_entry_state == 0) {
828 /* initialize with a fresh new string */
830 if (field != AudioFrames) {
831 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
840 string existing = label->get_text();
841 if (existing.length() >= field_length[field]) {
842 new_text = existing.substr (1, field_length[field] - 1);
844 new_text = existing.substr (0, field_length[field] - 1);
848 new_text += new_char;
849 label->set_text (new_text);
853 if (key_entry_state == field_length[field]) {
859 if (key_entry_state) {
866 // Check SMPTE fields for sanity (may also adjust fields)
867 smpte_sanitize_display();
872 // Bars should never be, unless this clock is for a duration
873 if (atoi(bars_label.get_text()) == 0 && !is_duration) {
874 bars_label.set_text("001");
876 // beats should never be 0, unless this clock is for a duration
877 if (atoi(beats_label.get_text()) == 0 && !is_duration) {
878 beats_label.set_text("01");
885 ValueChanged(); /* EMIT_SIGNAL */
888 /* move on to the next field.
896 minutes_ebox.grab_focus ();
899 seconds_ebox.grab_focus ();
902 frames_ebox.grab_focus ();
905 clock_base.grab_focus ();
910 clock_base.grab_focus ();
916 ms_minutes_ebox.grab_focus ();
919 ms_seconds_ebox.grab_focus ();
922 clock_base.grab_focus ();
928 beats_ebox.grab_focus ();
931 ticks_ebox.grab_focus ();
934 clock_base.grab_focus ();
947 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
951 Keyboard::magic_widget_grab_focus ();
955 hours_ebox.set_flags (Gtk::HAS_FOCUS);
956 hours_ebox.set_state (Gtk::STATE_ACTIVE);
959 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
960 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
963 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
964 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
967 frames_ebox.set_flags (Gtk::HAS_FOCUS);
968 frames_ebox.set_state (Gtk::STATE_ACTIVE);
972 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
973 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
977 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
978 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
981 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
982 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
985 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
986 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
989 bars_ebox.set_flags (Gtk::HAS_FOCUS);
990 bars_ebox.set_state (Gtk::STATE_ACTIVE);
993 beats_ebox.set_flags (Gtk::HAS_FOCUS);
994 beats_ebox.set_state (Gtk::STATE_ACTIVE);
997 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
998 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
1006 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
1011 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1012 hours_ebox.set_state (Gtk::STATE_NORMAL);
1015 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1016 minutes_ebox.set_state (Gtk::STATE_NORMAL);
1019 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1020 seconds_ebox.set_state (Gtk::STATE_NORMAL);
1023 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1024 frames_ebox.set_state (Gtk::STATE_NORMAL);
1028 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1029 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
1033 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1034 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
1037 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1038 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
1041 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1042 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1046 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1047 bars_ebox.set_state (Gtk::STATE_NORMAL);
1050 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1051 beats_ebox.set_state (Gtk::STATE_NORMAL);
1054 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1055 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1059 Keyboard::magic_widget_drop_focus ();
1065 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1068 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1070 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
1071 // we actually dragged so return without setting editing focus, or we shift clicked
1077 if (ops_menu == 0) {
1080 ops_menu->popup (1, ev->time);
1084 if (Keyboard::is_context_menu_event (ev)) {
1085 if (ops_menu == 0) {
1088 ops_menu->popup (1, ev->time);
1092 switch (ev->button) {
1096 hours_ebox.grab_focus();
1099 minutes_ebox.grab_focus();
1102 seconds_ebox.grab_focus();
1105 frames_ebox.grab_focus();
1109 audio_frames_ebox.grab_focus();
1113 ms_hours_ebox.grab_focus();
1116 ms_minutes_ebox.grab_focus();
1119 ms_seconds_ebox.grab_focus();
1123 bars_ebox.grab_focus ();
1126 beats_ebox.grab_focus ();
1129 ticks_ebox.grab_focus ();
1142 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
1144 if (session == 0) return false;
1146 nframes_t frames = 0;
1148 switch (ev->button) {
1150 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1152 ValueChanged (); /* EMIT_SIGNAL */
1155 /* make absolutely sure that the pointer is grabbed */
1156 gdk_pointer_grab(ev->window,false ,
1157 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1158 NULL,NULL,ev->time);
1161 drag_start_y = ev->y;
1166 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1168 ValueChanged (); /* EMIT_SIGNAL */
1173 /* used for context sensitive menu */
1186 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1192 nframes_t frames = 0;
1194 switch (ev->direction) {
1197 frames = get_frames (field);
1199 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1202 set (current_time() + frames, true);
1203 ValueChanged (); /* EMIT_SIGNAL */
1207 case GDK_SCROLL_DOWN:
1208 frames = get_frames (field);
1210 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1214 if ((double)current_time() - (double)frames < 0.0) {
1217 set (current_time() - frames, true);
1220 ValueChanged (); /* EMIT_SIGNAL */
1233 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1235 if (session == 0 || !dragging) {
1239 float pixel_frame_scale_factor = 0.2f;
1242 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1243 pixel_frame_scale_factor = 0.1f;
1247 if (Keyboard::modifier_state_contains (ev->state,
1248 Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) {
1250 pixel_frame_scale_factor = 0.025f;
1253 double y_delta = ev->y - drag_y;
1255 drag_accum += y_delta*pixel_frame_scale_factor;
1259 if (trunc(drag_accum) != 0) {
1264 dir = (drag_accum < 0 ? 1:-1);
1265 pos = current_time();
1266 frames = get_frames (field,pos,dir);
1268 if (frames != 0 && frames * drag_accum < current_time()) {
1270 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1278 ValueChanged(); /* EMIT_SIGNAL */
1287 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1290 nframes_t frames = 0;
1294 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1297 frames = (nframes_t) floor (60.0 * session->frame_rate());
1300 frames = session->frame_rate();
1303 frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second());
1311 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1314 frames = (nframes_t) floor (60.0 * session->frame_rate());
1317 frames = session->frame_rate();
1324 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1330 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1336 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1344 AudioClock::current_time (nframes_t pos) const
1350 ret = smpte_frame_from_display ();
1353 ret = bbt_frame_from_display (pos);
1357 ret = minsec_frame_from_display ();
1361 ret = audio_frame_from_display ();
1372 AudioClock::current_duration (nframes_t pos) const
1378 ret = smpte_frame_from_display ();
1381 ret = bbt_frame_duration_from_display (pos);
1385 ret = minsec_frame_from_display ();
1389 ret = audio_frame_from_display ();
1400 AudioClock::smpte_sanitize_display()
1402 // Check SMPTE fields for sanity, possibly adjusting values
1403 if (atoi(minutes_label.get_text()) > 59) {
1404 minutes_label.set_text("59");
1407 if (atoi(seconds_label.get_text()) > 59) {
1408 seconds_label.set_text("59");
1411 switch ((long)rint(session->smpte_frames_per_second())) {
1413 if (atoi(frames_label.get_text()) > 23) {
1414 frames_label.set_text("23");
1418 if (atoi(frames_label.get_text()) > 24) {
1419 frames_label.set_text("24");
1423 if (atoi(frames_label.get_text()) > 29) {
1424 frames_label.set_text("29");
1431 if (session->smpte_drop_frames()) {
1432 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1433 frames_label.set_text("02");
1439 AudioClock::smpte_frame_from_display () const
1448 smpte.hours = atoi (hours_label.get_text());
1449 smpte.minutes = atoi (minutes_label.get_text());
1450 smpte.seconds = atoi (seconds_label.get_text());
1451 smpte.frames = atoi (frames_label.get_text());
1452 smpte.rate = session->smpte_frames_per_second();
1453 smpte.drop= session->smpte_drop_frames();
1455 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1459 #define SMPTE_SAMPLE_TEST_1
1460 #define SMPTE_SAMPLE_TEST_2
1461 #define SMPTE_SAMPLE_TEST_3
1462 #define SMPTE_SAMPLE_TEST_4
1463 #define SMPTE_SAMPLE_TEST_5
1464 #define SMPTE_SAMPLE_TEST_6
1465 #define SMPTE_SAMPLE_TEST_7
1467 // Testcode for smpte<->sample conversions (P.S.)
1470 nframes_t oldsample = 0;
1472 nframes_t sample_increment;
1474 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1476 #ifdef SMPTE_SAMPLE_TEST_1
1477 // Test 1: use_offset = false, use_subframes = false
1478 cout << "use_offset = false, use_subframes = false" << endl;
1479 for (int i = 0; i < 108003; i++) {
1480 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1481 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1483 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1484 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1485 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1486 cout << "sample: " << sample1 << endl;
1487 cout << "sample: " << sample1 << " -> ";
1488 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1492 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1493 cout << "ERROR: smpte2 not equal smpte1" << endl;
1494 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1495 cout << "sample: " << sample1 << endl;
1496 cout << "sample: " << sample1 << " -> ";
1497 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1500 oldsample = sample1;
1501 session->smpte_increment( smpte1 );
1504 cout << "sample_increment: " << sample_increment << endl;
1505 cout << "sample: " << sample1 << " -> ";
1506 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1509 #ifdef SMPTE_SAMPLE_TEST_2
1510 // Test 2: use_offset = true, use_subframes = false
1511 cout << "use_offset = true, use_subframes = false" << endl;
1517 smpte1.subframes = 0;
1518 sample1 = oldsample = 0;
1520 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1521 cout << "Starting at sample: " << sample1 << " -> ";
1522 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1524 for (int i = 0; i < 108003; i++) {
1525 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1526 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1528 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1529 // cout << "sample: " << sample1 << endl;
1530 // cout << "sample: " << sample1 << " -> ";
1531 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1533 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1534 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1535 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1536 cout << "sample: " << sample1 << endl;
1537 cout << "sample: " << sample1 << " -> ";
1538 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1542 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1543 cout << "ERROR: smpte2 not equal smpte1" << endl;
1544 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1545 cout << "sample: " << sample1 << endl;
1546 cout << "sample: " << sample1 << " -> ";
1547 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1550 oldsample = sample1;
1551 session->smpte_increment( smpte1 );
1554 cout << "sample_increment: " << sample_increment << endl;
1555 cout << "sample: " << sample1 << " -> ";
1556 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1559 #ifdef SMPTE_SAMPLE_TEST_3
1560 // Test 3: use_offset = true, use_subframes = false, decrement
1561 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1563 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1564 cout << "Starting at sample: " << sample1 << " -> ";
1565 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1567 for (int i = 0; i < 108003; i++) {
1568 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1569 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1571 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1572 // cout << "sample: " << sample1 << endl;
1573 // cout << "sample: " << sample1 << " -> ";
1574 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1576 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1577 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1578 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1579 cout << "sample: " << sample1 << endl;
1580 cout << "sample: " << sample1 << " -> ";
1581 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1585 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1586 cout << "ERROR: smpte2 not equal smpte1" << endl;
1587 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1588 cout << "sample: " << sample1 << endl;
1589 cout << "sample: " << sample1 << " -> ";
1590 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1593 oldsample = sample1;
1594 session->smpte_decrement( smpte1 );
1597 cout << "sample_decrement: " << sample_increment << endl;
1598 cout << "sample: " << sample1 << " -> ";
1599 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1603 #ifdef SMPTE_SAMPLE_TEST_4
1604 // Test 4: use_offset = true, use_subframes = true
1605 cout << "use_offset = true, use_subframes = true" << endl;
1607 for (long sub = 5; sub < 80; sub += 5) {
1612 smpte1.subframes = 0;
1613 sample1 = oldsample = (sample_increment * sub) / 80;
1615 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1617 cout << "starting at sample: " << sample1 << " -> ";
1618 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1620 for (int i = 0; i < 108003; i++) {
1621 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1622 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1624 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1625 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1626 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1627 cout << "sample: " << sample1 << endl;
1628 cout << "sample: " << sample1 << " -> ";
1629 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1633 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1634 cout << "ERROR: smpte2 not equal smpte1" << endl;
1635 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1636 cout << "sample: " << sample1 << endl;
1637 cout << "sample: " << sample1 << " -> ";
1638 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1641 oldsample = sample1;
1642 session->smpte_increment( smpte1 );
1645 cout << "sample_increment: " << sample_increment << endl;
1646 cout << "sample: " << sample1 << " -> ";
1647 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1649 for (int i = 0; i < 108003; i++) {
1650 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1651 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1653 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1654 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1655 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1656 cout << "sample: " << sample1 << endl;
1657 cout << "sample: " << sample1 << " -> ";
1658 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1662 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1663 cout << "ERROR: smpte2 not equal smpte1" << endl;
1664 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1665 cout << "sample: " << sample1 << endl;
1666 cout << "sample: " << sample1 << " -> ";
1667 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1670 oldsample = sample1;
1671 session->smpte_decrement( smpte1 );
1674 cout << "sample_decrement: " << sample_increment << endl;
1675 cout << "sample: " << sample1 << " -> ";
1676 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1681 #ifdef SMPTE_SAMPLE_TEST_5
1682 // Test 5: use_offset = true, use_subframes = false, increment seconds
1683 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1689 smpte1.subframes = 0;
1690 sample1 = oldsample = 0;
1691 sample_increment = session->frame_rate();
1693 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1694 cout << "Starting at sample: " << sample1 << " -> ";
1695 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1697 for (int i = 0; i < 3600; i++) {
1698 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1699 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1701 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1702 // cout << "sample: " << sample1 << endl;
1703 // cout << "sample: " << sample1 << " -> ";
1704 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1706 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1708 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1712 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1713 cout << "ERROR: smpte2 not equal smpte1" << endl;
1714 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1715 cout << "sample: " << sample1 << endl;
1716 cout << "sample: " << sample1 << " -> ";
1717 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1720 oldsample = sample1;
1721 session->smpte_increment_seconds( smpte1 );
1724 cout << "sample_increment: " << sample_increment << endl;
1725 cout << "sample: " << sample1 << " -> ";
1726 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1730 #ifdef SMPTE_SAMPLE_TEST_6
1731 // Test 6: use_offset = true, use_subframes = false, increment minutes
1732 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1738 smpte1.subframes = 0;
1739 sample1 = oldsample = 0;
1740 sample_increment = session->frame_rate() * 60;
1742 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1743 cout << "Starting at sample: " << sample1 << " -> ";
1744 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1746 for (int i = 0; i < 60; i++) {
1747 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1748 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1750 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1751 // cout << "sample: " << sample1 << endl;
1752 // cout << "sample: " << sample1 << " -> ";
1753 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1755 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1757 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1761 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1762 cout << "ERROR: smpte2 not equal smpte1" << endl;
1763 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1764 cout << "sample: " << sample1 << endl;
1765 cout << "sample: " << sample1 << " -> ";
1766 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1769 oldsample = sample1;
1770 session->smpte_increment_minutes( smpte1 );
1773 cout << "sample_increment: " << sample_increment << endl;
1774 cout << "sample: " << sample1 << " -> ";
1775 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1778 #ifdef SMPTE_SAMPLE_TEST_7
1779 // Test 7: use_offset = true, use_subframes = false, increment hours
1780 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1786 smpte1.subframes = 0;
1787 sample1 = oldsample = 0;
1788 sample_increment = session->frame_rate() * 60 * 60;
1790 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1791 cout << "Starting at sample: " << sample1 << " -> ";
1792 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1794 for (int i = 0; i < 10; i++) {
1795 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1796 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1798 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1799 // cout << "sample: " << sample1 << endl;
1800 // cout << "sample: " << sample1 << " -> ";
1801 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1803 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1805 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1809 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1810 cout << "ERROR: smpte2 not equal smpte1" << endl;
1811 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1812 cout << "sample: " << sample1 << endl;
1813 cout << "sample: " << sample1 << " -> ";
1814 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1817 oldsample = sample1;
1818 session->smpte_increment_hours( smpte1 );
1821 cout << "sample_increment: " << sample_increment << endl;
1822 cout << "sample: " << sample1 << " -> ";
1823 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1832 AudioClock::minsec_frame_from_display () const
1838 int hrs = atoi (ms_hours_label.get_text());
1839 int mins = atoi (ms_minutes_label.get_text());
1840 float secs = atof (ms_seconds_label.get_text());
1842 nframes_t sr = session->frame_rate();
1844 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1848 AudioClock::bbt_frame_from_display (nframes_t pos) const
1851 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1856 any.type = AnyTime::BBT;
1858 any.bbt.bars = atoi (bars_label.get_text());
1859 any.bbt.beats = atoi (beats_label.get_text());
1860 any.bbt.ticks = atoi (ticks_label.get_text());
1862 nframes_t ret = session->convert_to_frames_at (pos, any);
1869 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1872 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1879 bbt.bars = atoi (bars_label.get_text());
1880 bbt.beats = atoi (beats_label.get_text());
1881 bbt.ticks = atoi (ticks_label.get_text());
1883 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1887 AudioClock::audio_frame_from_display () const
1889 return (nframes_t) atoi (audio_frames_label.get_text());
1893 AudioClock::build_ops_menu ()
1895 using namespace Menu_Helpers;
1896 ops_menu = new Menu;
1897 MenuList& ops_items = ops_menu->items();
1898 ops_menu->set_name ("ArdourContextMenu");
1900 if (!Profile->get_sae()) {
1901 ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1903 ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1904 ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1905 ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1906 ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1910 AudioClock::set_mode (Mode m)
1912 /* slightly tricky: this is called from within the ARDOUR_UI
1913 constructor by some of its clock members. at that time
1914 the instance pointer is unset, so we have to be careful.
1915 the main idea is to drop keyboard focus in case we had
1916 started editing the clock and then we switch clock mode.
1919 clock_base.grab_focus ();
1925 clock_base.remove ();
1931 clock_base.add (smpte_packer_hbox);
1935 clock_base.add (bbt_packer_hbox);
1939 clock_base.add (minsec_packer_hbox);
1943 clock_base.add (frames_packer_hbox);
1947 clock_base.add (off_hbox);
1951 set_size_requests ();
1953 set (last_when, true);
1954 clock_base.show_all ();
1955 key_entry_state = 0;
1957 if (!is_transient) {
1958 ModeChanged (); /* EMIT SIGNAL */
1963 AudioClock::set_size_requests ()
1965 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
1969 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
1970 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
1971 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
1972 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
1976 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
1977 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
1978 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
1982 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
1983 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
1984 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
1988 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
1992 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);