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] = {
53 2, /* Timecode_Hours */
54 2, /* Timecode_Minutes */
55 2, /* Timecode_Seconds */
56 2, /* Timecode_Frames */
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),
87 bbt_reference_time = -1;
90 frames_upper_info_label = manage (new Label);
91 frames_lower_info_label = manage (new Label);
92 timecode_upper_info_label = manage (new Label);
93 timecode_lower_info_label = manage (new Label);
94 bbt_upper_info_label = manage (new Label);
95 bbt_lower_info_label = manage (new Label);
97 frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
98 frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
99 timecode_upper_info_label->set_name ("AudioClockTimecodeUpperInfo");
100 timecode_lower_info_label->set_name ("AudioClockTimecodeLowerInfo");
101 bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
102 bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
104 Gtkmm2ext::set_size_request_to_display_given_text(*timecode_upper_info_label, "23.98",0,0);
105 Gtkmm2ext::set_size_request_to_display_given_text(*timecode_lower_info_label, "NDF",0,0);
107 Gtkmm2ext::set_size_request_to_display_given_text(*bbt_upper_info_label, "88|88",0,0);
108 Gtkmm2ext::set_size_request_to_display_given_text(*bbt_lower_info_label, "888.88",0,0);
110 frames_info_box.pack_start (*frames_upper_info_label, true, true);
111 frames_info_box.pack_start (*frames_lower_info_label, true, true);
112 timecode_info_box.pack_start (*timecode_upper_info_label, true, true);
113 timecode_info_box.pack_start (*timecode_lower_info_label, true, true);
114 bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
115 bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
118 frames_upper_info_label = 0;
119 frames_lower_info_label = 0;
120 timecode_upper_info_label = 0;
121 timecode_lower_info_label = 0;
122 bbt_upper_info_label = 0;
123 bbt_lower_info_label = 0;
126 audio_frames_ebox.add (audio_frames_label);
128 frames_packer.set_homogeneous (false);
129 frames_packer.set_border_width (2);
130 frames_packer.pack_start (audio_frames_ebox, false, false);
133 frames_packer.pack_start (frames_info_box, false, false, 5);
136 frames_packer_hbox.pack_start (frames_packer, true, false);
138 hours_ebox.add (hours_label);
139 minutes_ebox.add (minutes_label);
140 seconds_ebox.add (seconds_label);
141 frames_ebox.add (frames_label);
142 bars_ebox.add (bars_label);
143 beats_ebox.add (beats_label);
144 ticks_ebox.add (ticks_label);
145 ms_hours_ebox.add (ms_hours_label);
146 ms_minutes_ebox.add (ms_minutes_label);
147 ms_seconds_ebox.add (ms_seconds_label);
149 timecode_packer.set_homogeneous (false);
150 timecode_packer.set_border_width (2);
151 timecode_packer.pack_start (hours_ebox, false, false);
152 timecode_packer.pack_start (colon1, false, false);
153 timecode_packer.pack_start (minutes_ebox, false, false);
154 timecode_packer.pack_start (colon2, false, false);
155 timecode_packer.pack_start (seconds_ebox, false, false);
156 timecode_packer.pack_start (colon3, false, false);
157 timecode_packer.pack_start (frames_ebox, false, false);
160 timecode_packer.pack_start (timecode_info_box, false, false, 5);
163 timecode_packer_hbox.pack_start (timecode_packer, true, false);
165 bbt_packer.set_homogeneous (false);
166 bbt_packer.set_border_width (2);
167 bbt_packer.pack_start (bars_ebox, false, false);
168 bbt_packer.pack_start (b1, false, false);
169 bbt_packer.pack_start (beats_ebox, false, false);
170 bbt_packer.pack_start (b2, false, false);
171 bbt_packer.pack_start (ticks_ebox, false, false);
174 bbt_packer.pack_start (bbt_info_box, false, false, 5);
177 bbt_packer_hbox.pack_start (bbt_packer, true, false);
179 minsec_packer.set_homogeneous (false);
180 minsec_packer.set_border_width (2);
181 minsec_packer.pack_start (ms_hours_ebox, false, false);
182 minsec_packer.pack_start (colon4, false, false);
183 minsec_packer.pack_start (ms_minutes_ebox, false, false);
184 minsec_packer.pack_start (colon5, false, false);
185 minsec_packer.pack_start (ms_seconds_ebox, false, false);
187 minsec_packer_hbox.pack_start (minsec_packer, true, false);
189 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
190 clock_frame.set_name ("BaseFrame");
192 clock_frame.add (clock_base);
194 set_widget_name (widget_name);
196 _mode = BBT; /* lie to force mode switch */
199 pack_start (clock_frame, true, true);
201 /* the clock base handles button releases for menu popup regardless of
202 editable status. if the clock is editable, the clock base is where
203 we pass focus to after leaving the last editable "field", which
204 will then shutdown editing till the user starts it up again.
206 it does this because the focus out event on the field disables
207 keyboard event handling, and we don't connect anything up to
208 notice focus in on the clock base. hence, keyboard event handling
212 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
213 clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), Timecode_Hours));
215 Session::TimecodeOffsetChanged.connect (mem_fun (*this, &AudioClock::timecode_offset_changed));
221 set (last_when, true);
224 clocks.push_back (this);
229 AudioClock::set_widget_name (string name)
231 Widget::set_name (name);
233 clock_base.set_name (name);
235 audio_frames_label.set_name (name);
236 hours_label.set_name (name);
237 minutes_label.set_name (name);
238 seconds_label.set_name (name);
239 frames_label.set_name (name);
240 bars_label.set_name (name);
241 beats_label.set_name (name);
242 ticks_label.set_name (name);
243 ms_hours_label.set_name (name);
244 ms_minutes_label.set_name (name);
245 ms_seconds_label.set_name (name);
246 hours_ebox.set_name (name);
247 minutes_ebox.set_name (name);
248 seconds_ebox.set_name (name);
249 frames_ebox.set_name (name);
250 audio_frames_ebox.set_name (name);
251 bars_ebox.set_name (name);
252 beats_ebox.set_name (name);
253 ticks_ebox.set_name (name);
254 ms_hours_ebox.set_name (name);
255 ms_minutes_ebox.set_name (name);
256 ms_seconds_ebox.set_name (name);
258 colon1.set_name (name);
259 colon2.set_name (name);
260 colon3.set_name (name);
261 colon4.set_name (name);
262 colon5.set_name (name);
270 AudioClock::setup_events ()
272 clock_base.set_flags (Gtk::CAN_FOCUS);
274 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);
275 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);
276 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);
277 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);
278 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);
279 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);
280 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);
281 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);
282 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);
283 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);
284 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);
286 hours_ebox.set_flags (Gtk::CAN_FOCUS);
287 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
288 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
289 frames_ebox.set_flags (Gtk::CAN_FOCUS);
290 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
291 bars_ebox.set_flags (Gtk::CAN_FOCUS);
292 beats_ebox.set_flags (Gtk::CAN_FOCUS);
293 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
294 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
295 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
296 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
298 hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Hours));
299 minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Minutes));
300 seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Seconds));
301 frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Frames));
302 audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
303 bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
304 beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
305 ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
306 ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
307 ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
308 ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
310 hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Hours));
311 minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Minutes));
312 seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Seconds));
313 frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Frames));
314 audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
315 bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
316 beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
317 ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
318 ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
319 ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
320 ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
322 hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Hours));
323 minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Minutes));
324 seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Seconds));
325 frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Frames));
326 audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
327 bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
328 beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
329 ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
330 ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
331 ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
332 ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
334 hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Hours));
335 minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Minutes));
336 seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Seconds));
337 frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Frames));
338 audio_frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
339 bars_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
340 beats_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
341 ticks_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
342 ms_hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
343 ms_minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
344 ms_seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
346 hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Hours));
347 minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Minutes));
348 seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Seconds));
349 frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Frames));
350 audio_frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), AudioFrames));
351 bars_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Bars));
352 beats_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Beats));
353 ticks_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Ticks));
354 ms_hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Hours));
355 ms_minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Minutes));
356 ms_seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Seconds));
358 hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Hours));
359 minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Minutes));
360 seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Seconds));
361 frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Frames));
362 audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
363 bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
364 beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
365 ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
366 ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
367 ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
368 ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
370 hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Hours));
371 minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Minutes));
372 seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Seconds));
373 frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Frames));
374 audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
375 bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
376 beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
377 ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
378 ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
379 ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
380 ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
382 hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Hours));
383 minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Minutes));
384 seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Seconds));
385 frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Frames));
386 audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
387 bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
388 beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
389 ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
390 ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
391 ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
392 ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
394 clock_base.signal_focus_in_event().connect (mem_fun (*this, &AudioClock::drop_focus_handler));
398 AudioClock::drop_focus_handler (GdkEventFocus*)
400 Keyboard::magic_widget_drop_focus ();
405 AudioClock::on_realize ()
409 /* styles are not available until the widgets are bound to a window */
411 set_size_requests ();
415 AudioClock::set (nframes_t when, bool force, nframes_t offset, char which)
418 if ((!force && !is_visible()) || session == 0) {
422 if (when == last_when && !offset && !force) {
426 bool pdelta = Config->get_primary_clock_delta_edit_cursor();
427 bool sdelta = Config->get_secondary_clock_delta_edit_cursor();
429 if (offset && which == 'p' && pdelta) {
430 when = (when > offset) ? when - offset : offset - when;
431 } else if (offset && which == 's' && sdelta) {
432 when = (when > offset) ? when - offset : offset - when;
435 if (which == 'p' && pdelta && !last_pdelta) {
436 set_widget_name("TransportClockDisplayDelta");
438 } else if (which == 'p' && !pdelta && last_pdelta) {
439 set_widget_name("TransportClockDisplay");
441 } else if (which == 's' && sdelta && !last_sdelta) {
442 set_widget_name("SecondaryClockDisplayDelta");
444 } else if (which == 's' && !sdelta && last_sdelta) {
445 set_widget_name("SecondaryClockDisplay");
451 set_timecode (when, force);
455 set_bbt (when, force);
459 set_minsec (when, force);
463 set_frames (when, force);
474 AudioClock::timecode_offset_changed ()
481 current = current_duration();
483 current = current_time ();
493 AudioClock::set_frames (nframes_t when, bool /*force*/)
496 snprintf (buf, sizeof (buf), "%u", when);
497 audio_frames_label.set_text (buf);
499 if (frames_upper_info_label) {
500 nframes_t rate = session->frame_rate();
502 if (fmod (rate, 1000.0) == 0.000) {
503 sprintf (buf, "%uK", rate/1000);
505 sprintf (buf, "%.3fK", rate/1000.0f);
508 if (frames_upper_info_label->get_text() != buf) {
509 frames_upper_info_label->set_text (buf);
512 float vid_pullup = session->config.get_video_pullup();
514 if (vid_pullup == 0.0) {
515 if (frames_lower_info_label->get_text () != _("none")) {
516 frames_lower_info_label->set_text(_("none"));
519 sprintf (buf, "%-6.4f", vid_pullup);
520 if (frames_lower_info_label->get_text() != buf) {
521 frames_lower_info_label->set_text (buf);
528 AudioClock::set_minsec (nframes_t when, bool force)
537 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
538 left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
539 mins = (int) floor (left / (session->frame_rate() * 60.0f));
540 left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
541 secs = left / (float) session->frame_rate();
543 if (force || hrs != ms_last_hrs) {
544 sprintf (buf, "%02d", hrs);
545 ms_hours_label.set_text (buf);
549 if (force || mins != ms_last_mins) {
550 sprintf (buf, "%02d", mins);
551 ms_minutes_label.set_text (buf);
555 if (force || secs != ms_last_secs) {
556 sprintf (buf, "%06.3f", secs);
557 ms_seconds_label.set_text (buf);
563 AudioClock::set_timecode (nframes_t when, bool force)
566 Timecode::Time timecode;
569 session->timecode_duration (when, timecode);
571 session->timecode_time (when, timecode);
574 if (force || timecode.hours != last_hrs || timecode.negative != last_negative) {
575 if (timecode.negative) {
576 sprintf (buf, "-%02" PRIu32, timecode.hours);
578 sprintf (buf, " %02" PRIu32, timecode.hours);
580 hours_label.set_text (buf);
581 last_hrs = timecode.hours;
582 last_negative = timecode.negative;
585 if (force || timecode.minutes != last_mins) {
586 sprintf (buf, "%02" PRIu32, timecode.minutes);
587 minutes_label.set_text (buf);
588 last_mins = timecode.minutes;
591 if (force || timecode.seconds != last_secs) {
592 sprintf (buf, "%02" PRIu32, timecode.seconds);
593 seconds_label.set_text (buf);
594 last_secs = timecode.seconds;
597 if (force || timecode.frames != last_frames) {
598 sprintf (buf, "%02" PRIu32, timecode.frames);
599 frames_label.set_text (buf);
600 last_frames = timecode.frames;
603 if (timecode_upper_info_label) {
604 double timecode_frames = session->timecode_frames_per_second();
606 if ( fmod(timecode_frames, 1.0) == 0.0) {
607 sprintf (buf, "%u", int (timecode_frames));
609 sprintf (buf, "%.2f", timecode_frames);
612 if (timecode_upper_info_label->get_text() != buf) {
613 timecode_upper_info_label->set_text (buf);
616 if ((fabs(timecode_frames - 29.97) < 0.0001) || timecode_frames == 30) {
617 if (session->timecode_drop_frames()) {
620 sprintf (buf, "NDF");
623 // there is no drop frame alternative
627 if (timecode_lower_info_label->get_text() != buf) {
628 timecode_lower_info_label->set_text (buf);
634 AudioClock::set_bbt (nframes_t when, bool force)
639 /* handle a common case */
646 session->tempo_map().bbt_time (when, bbt);
651 session->tempo_map().bbt_time (when, bbt);
654 sprintf (buf, "%03" PRIu32, bbt.bars);
655 if (force || bars_label.get_text () != buf) {
656 bars_label.set_text (buf);
658 sprintf (buf, "%02" PRIu32, bbt.beats);
659 if (force || beats_label.get_text () != buf) {
660 beats_label.set_text (buf);
662 sprintf (buf, "%04" PRIu32, bbt.ticks);
663 if (force || ticks_label.get_text () != buf) {
664 ticks_label.set_text (buf);
667 if (bbt_upper_info_label) {
670 if (bbt_reference_time < 0) {
673 pos = bbt_reference_time;
676 TempoMetric m (session->tempo_map().metric_at (pos));
678 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
679 if (bbt_lower_info_label->get_text() != buf) {
680 bbt_lower_info_label->set_text (buf);
682 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
683 if (bbt_upper_info_label->get_text() != buf) {
684 bbt_upper_info_label->set_text (buf);
690 AudioClock::set_session (Session *s)
697 XMLNode* node = session->extra_xml (X_("ClockModes"));
698 AudioClock::Mode amode;
701 if ((prop = node->property (_name)) != 0) {
702 amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
707 set (last_when, true);
716 hours_ebox.grab_focus ();
720 bars_ebox.grab_focus ();
724 ms_hours_ebox.grab_focus ();
728 frames_ebox.grab_focus ();
738 AudioClock::field_key_press_event (GdkEventKey */*ev*/, Field /*field*/)
740 /* all key activity is handled on key release */
745 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
750 bool move_on = false;
754 label = &hours_label;
756 case Timecode_Minutes:
757 label = &minutes_label;
759 case Timecode_Seconds:
760 label = &seconds_label;
762 case Timecode_Frames:
763 label = &frames_label;
767 label = &audio_frames_label;
771 label = &ms_hours_label;
774 label = &ms_minutes_label;
777 label = &ms_seconds_label;
784 label = &beats_label;
787 label = &ticks_label;
793 switch (ev->keyval) {
837 if (_mode == MinSec && field == MS_Seconds) {
852 clock_base.grab_focus ();
853 ChangeAborted(); /* EMIT SIGNAL */
862 if (key_entry_state == 0) {
864 /* initialize with a fresh new string */
866 if (field != AudioFrames) {
867 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
876 string existing = label->get_text();
877 if (existing.length() >= field_length[field]) {
878 new_text = existing.substr (1, field_length[field] - 1);
880 new_text = existing.substr (0, field_length[field] - 1);
884 new_text += new_char;
885 label->set_text (new_text);
889 if (key_entry_state == field_length[field]) {
895 if (key_entry_state) {
899 case Timecode_Minutes:
900 case Timecode_Seconds:
901 case Timecode_Frames:
902 // Check Timecode fields for sanity (may also adjust fields)
903 timecode_sanitize_display();
908 // Bars should never be, unless this clock is for a duration
909 if (atoi(bars_label.get_text()) == 0 && !is_duration) {
910 bars_label.set_text("001");
912 // beats should never be 0, unless this clock is for a duration
913 if (atoi(beats_label.get_text()) == 0 && !is_duration) {
914 beats_label.set_text("01");
921 ValueChanged(); /* EMIT_SIGNAL */
924 /* move on to the next field.
932 minutes_ebox.grab_focus ();
934 case Timecode_Minutes:
935 seconds_ebox.grab_focus ();
937 case Timecode_Seconds:
938 frames_ebox.grab_focus ();
940 case Timecode_Frames:
941 clock_base.grab_focus ();
946 clock_base.grab_focus ();
952 ms_minutes_ebox.grab_focus ();
955 ms_seconds_ebox.grab_focus ();
958 clock_base.grab_focus ();
964 beats_ebox.grab_focus ();
967 ticks_ebox.grab_focus ();
970 clock_base.grab_focus ();
979 //if user hit Enter, lose focus
980 switch (ev->keyval) {
983 clock_base.grab_focus ();
990 AudioClock::field_focus_in_event (GdkEventFocus */*ev*/, Field field)
994 Keyboard::magic_widget_grab_focus ();
998 hours_ebox.set_flags (Gtk::HAS_FOCUS);
999 hours_ebox.set_state (Gtk::STATE_ACTIVE);
1001 case Timecode_Minutes:
1002 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
1003 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
1005 case Timecode_Seconds:
1006 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
1007 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
1009 case Timecode_Frames:
1010 frames_ebox.set_flags (Gtk::HAS_FOCUS);
1011 frames_ebox.set_state (Gtk::STATE_ACTIVE);
1015 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
1016 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
1020 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
1021 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
1024 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
1025 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
1028 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
1029 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
1032 bars_ebox.set_flags (Gtk::HAS_FOCUS);
1033 bars_ebox.set_state (Gtk::STATE_ACTIVE);
1036 beats_ebox.set_flags (Gtk::HAS_FOCUS);
1037 beats_ebox.set_state (Gtk::STATE_ACTIVE);
1040 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
1041 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
1049 AudioClock::field_focus_out_event (GdkEventFocus */*ev*/, Field field)
1053 case Timecode_Hours:
1054 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1055 hours_ebox.set_state (Gtk::STATE_NORMAL);
1057 case Timecode_Minutes:
1058 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1059 minutes_ebox.set_state (Gtk::STATE_NORMAL);
1061 case Timecode_Seconds:
1062 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1063 seconds_ebox.set_state (Gtk::STATE_NORMAL);
1065 case Timecode_Frames:
1066 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1067 frames_ebox.set_state (Gtk::STATE_NORMAL);
1071 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1072 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
1076 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1077 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
1080 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1081 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
1084 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1085 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1089 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1090 bars_ebox.set_state (Gtk::STATE_NORMAL);
1093 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1094 beats_ebox.set_state (Gtk::STATE_NORMAL);
1097 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1098 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1102 Keyboard::magic_widget_drop_focus ();
1108 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1111 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1113 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
1114 // we actually dragged so return without setting editing focus, or we shift clicked
1120 if (ops_menu == 0) {
1123 ops_menu->popup (1, ev->time);
1127 if (Keyboard::is_context_menu_event (ev)) {
1128 if (ops_menu == 0) {
1131 ops_menu->popup (1, ev->time);
1135 switch (ev->button) {
1138 case Timecode_Hours:
1139 hours_ebox.grab_focus();
1141 case Timecode_Minutes:
1142 minutes_ebox.grab_focus();
1144 case Timecode_Seconds:
1145 seconds_ebox.grab_focus();
1147 case Timecode_Frames:
1148 frames_ebox.grab_focus();
1152 audio_frames_ebox.grab_focus();
1156 ms_hours_ebox.grab_focus();
1159 ms_minutes_ebox.grab_focus();
1162 ms_seconds_ebox.grab_focus();
1166 bars_ebox.grab_focus ();
1169 beats_ebox.grab_focus ();
1172 ticks_ebox.grab_focus ();
1185 AudioClock::field_button_press_event (GdkEventButton *ev, Field /*field*/)
1191 nframes_t frames = 0;
1193 switch (ev->button) {
1195 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1197 ValueChanged (); /* EMIT_SIGNAL */
1200 /* make absolutely sure that the pointer is grabbed */
1201 gdk_pointer_grab(ev->window,false ,
1202 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1203 NULL,NULL,ev->time);
1206 drag_start_y = ev->y;
1211 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1213 ValueChanged (); /* EMIT_SIGNAL */
1218 /* used for context sensitive menu */
1231 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1237 nframes_t frames = 0;
1239 switch (ev->direction) {
1242 frames = get_frames (field);
1244 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1247 set (current_time() + frames, true);
1248 ValueChanged (); /* EMIT_SIGNAL */
1252 case GDK_SCROLL_DOWN:
1253 frames = get_frames (field);
1255 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1259 if ((double)current_time() - (double)frames < 0.0) {
1262 set (current_time() - frames, true);
1265 ValueChanged (); /* EMIT_SIGNAL */
1278 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1280 if (session == 0 || !dragging) {
1284 float pixel_frame_scale_factor = 0.2f;
1287 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1288 pixel_frame_scale_factor = 0.1f;
1292 if (Keyboard::modifier_state_contains (ev->state,
1293 Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) {
1295 pixel_frame_scale_factor = 0.025f;
1298 double y_delta = ev->y - drag_y;
1300 drag_accum += y_delta*pixel_frame_scale_factor;
1304 if (trunc(drag_accum) != 0) {
1309 dir = (drag_accum < 0 ? 1:-1);
1310 pos = current_time();
1311 frames = get_frames (field,pos,dir);
1313 if (frames != 0 && frames * drag_accum < current_time()) {
1315 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1323 ValueChanged(); /* EMIT_SIGNAL */
1332 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1335 nframes_t frames = 0;
1338 case Timecode_Hours:
1339 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1341 case Timecode_Minutes:
1342 frames = (nframes_t) floor (60.0 * session->frame_rate());
1344 case Timecode_Seconds:
1345 frames = session->frame_rate();
1347 case Timecode_Frames:
1348 frames = (nframes_t) floor (session->frame_rate() / session->timecode_frames_per_second());
1356 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1359 frames = (nframes_t) floor (60.0 * session->frame_rate());
1362 frames = session->frame_rate();
1369 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1375 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1381 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1389 AudioClock::current_time (nframes_t pos) const
1395 ret = timecode_frame_from_display ();
1398 ret = bbt_frame_from_display (pos);
1402 ret = minsec_frame_from_display ();
1406 ret = audio_frame_from_display ();
1417 AudioClock::current_duration (nframes_t pos) const
1423 ret = timecode_frame_from_display ();
1426 ret = bbt_frame_duration_from_display (pos);
1430 ret = minsec_frame_from_display ();
1434 ret = audio_frame_from_display ();
1445 AudioClock::timecode_sanitize_display()
1447 // Check Timecode fields for sanity, possibly adjusting values
1448 if (atoi(minutes_label.get_text()) > 59) {
1449 minutes_label.set_text("59");
1452 if (atoi(seconds_label.get_text()) > 59) {
1453 seconds_label.set_text("59");
1456 switch ((long)rint(session->timecode_frames_per_second())) {
1458 if (atoi(frames_label.get_text()) > 23) {
1459 frames_label.set_text("23");
1463 if (atoi(frames_label.get_text()) > 24) {
1464 frames_label.set_text("24");
1468 if (atoi(frames_label.get_text()) > 29) {
1469 frames_label.set_text("29");
1476 if (session->timecode_drop_frames()) {
1477 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1478 frames_label.set_text("02");
1484 AudioClock::timecode_frame_from_display () const
1490 Timecode::Time timecode;
1493 timecode.hours = atoi (hours_label.get_text());
1494 timecode.minutes = atoi (minutes_label.get_text());
1495 timecode.seconds = atoi (seconds_label.get_text());
1496 timecode.frames = atoi (frames_label.get_text());
1497 timecode.rate = session->timecode_frames_per_second();
1498 timecode.drop= session->timecode_drop_frames();
1500 session->timecode_to_sample( timecode, sample, false /* use_offset */, false /* use_subframes */ );
1504 #define Timecode_SAMPLE_TEST_1
1505 #define Timecode_SAMPLE_TEST_2
1506 #define Timecode_SAMPLE_TEST_3
1507 #define Timecode_SAMPLE_TEST_4
1508 #define Timecode_SAMPLE_TEST_5
1509 #define Timecode_SAMPLE_TEST_6
1510 #define Timecode_SAMPLE_TEST_7
1512 // Testcode for timecode<->sample conversions (P.S.)
1513 Timecode::Time timecode1;
1515 nframes_t oldsample = 0;
1516 Timecode::Time timecode2;
1517 nframes_t sample_increment;
1519 sample_increment = (long)rint(session->frame_rate() / session->timecode_frames_per_second);
1521 #ifdef Timecode_SAMPLE_TEST_1
1522 // Test 1: use_offset = false, use_subframes = false
1523 cout << "use_offset = false, use_subframes = false" << endl;
1524 for (int i = 0; i < 108003; i++) {
1525 session->timecode_to_sample( timecode1, sample1, false /* use_offset */, false /* use_subframes */ );
1526 session->sample_to_timecode( sample1, timecode2, false /* use_offset */, false /* use_subframes */ );
1528 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1529 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1530 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1531 cout << "sample: " << sample1 << endl;
1532 cout << "sample: " << sample1 << " -> ";
1533 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1537 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1538 cout << "ERROR: timecode2 not equal timecode1" << endl;
1539 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1540 cout << "sample: " << sample1 << endl;
1541 cout << "sample: " << sample1 << " -> ";
1542 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1545 oldsample = sample1;
1546 session->timecode_increment( timecode1 );
1549 cout << "sample_increment: " << sample_increment << endl;
1550 cout << "sample: " << sample1 << " -> ";
1551 cout << "timecode: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1554 #ifdef Timecode_SAMPLE_TEST_2
1555 // Test 2: use_offset = true, use_subframes = false
1556 cout << "use_offset = true, use_subframes = false" << endl;
1558 timecode1.hours = 0;
1559 timecode1.minutes = 0;
1560 timecode1.seconds = 0;
1561 timecode1.frames = 0;
1562 timecode1.subframes = 0;
1563 sample1 = oldsample = 0;
1565 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1566 cout << "Starting at sample: " << sample1 << " -> ";
1567 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1569 for (int i = 0; i < 108003; i++) {
1570 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1571 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1573 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1574 // cout << "sample: " << sample1 << endl;
1575 // cout << "sample: " << sample1 << " -> ";
1576 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1578 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1579 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1580 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1581 cout << "sample: " << sample1 << endl;
1582 cout << "sample: " << sample1 << " -> ";
1583 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1587 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1588 cout << "ERROR: timecode2 not equal timecode1" << endl;
1589 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1590 cout << "sample: " << sample1 << endl;
1591 cout << "sample: " << sample1 << " -> ";
1592 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1595 oldsample = sample1;
1596 session->timecode_increment( timecode1 );
1599 cout << "sample_increment: " << sample_increment << endl;
1600 cout << "sample: " << sample1 << " -> ";
1601 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1604 #ifdef Timecode_SAMPLE_TEST_3
1605 // Test 3: use_offset = true, use_subframes = false, decrement
1606 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1608 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1609 cout << "Starting at sample: " << sample1 << " -> ";
1610 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1612 for (int i = 0; i < 108003; i++) {
1613 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1614 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1616 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1617 // cout << "sample: " << sample1 << endl;
1618 // cout << "sample: " << sample1 << " -> ";
1619 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1621 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1622 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1623 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1624 cout << "sample: " << sample1 << endl;
1625 cout << "sample: " << sample1 << " -> ";
1626 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1630 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1631 cout << "ERROR: timecode2 not equal timecode1" << endl;
1632 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1633 cout << "sample: " << sample1 << endl;
1634 cout << "sample: " << sample1 << " -> ";
1635 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1638 oldsample = sample1;
1639 session->timecode_decrement( timecode1 );
1642 cout << "sample_decrement: " << sample_increment << endl;
1643 cout << "sample: " << sample1 << " -> ";
1644 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1648 #ifdef Timecode_SAMPLE_TEST_4
1649 // Test 4: use_offset = true, use_subframes = true
1650 cout << "use_offset = true, use_subframes = true" << endl;
1652 for (long sub = 5; sub < 80; sub += 5) {
1653 timecode1.hours = 0;
1654 timecode1.minutes = 0;
1655 timecode1.seconds = 0;
1656 timecode1.frames = 0;
1657 timecode1.subframes = 0;
1658 sample1 = oldsample = (sample_increment * sub) / 80;
1660 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, true /* use_subframes */ );
1662 cout << "starting at sample: " << sample1 << " -> ";
1663 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1665 for (int i = 0; i < 108003; i++) {
1666 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1667 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1669 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1670 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1671 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1672 cout << "sample: " << sample1 << endl;
1673 cout << "sample: " << sample1 << " -> ";
1674 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1678 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1679 cout << "ERROR: timecode2 not equal timecode1" << endl;
1680 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1681 cout << "sample: " << sample1 << endl;
1682 cout << "sample: " << sample1 << " -> ";
1683 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1686 oldsample = sample1;
1687 session->timecode_increment( timecode1 );
1690 cout << "sample_increment: " << sample_increment << endl;
1691 cout << "sample: " << sample1 << " -> ";
1692 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1694 for (int i = 0; i < 108003; i++) {
1695 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1696 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1698 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1699 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1700 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1701 cout << "sample: " << sample1 << endl;
1702 cout << "sample: " << sample1 << " -> ";
1703 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1707 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1708 cout << "ERROR: timecode2 not equal timecode1" << endl;
1709 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1710 cout << "sample: " << sample1 << endl;
1711 cout << "sample: " << sample1 << " -> ";
1712 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1715 oldsample = sample1;
1716 session->timecode_decrement( timecode1 );
1719 cout << "sample_decrement: " << sample_increment << endl;
1720 cout << "sample: " << sample1 << " -> ";
1721 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1726 #ifdef Timecode_SAMPLE_TEST_5
1727 // Test 5: use_offset = true, use_subframes = false, increment seconds
1728 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1730 timecode1.hours = 0;
1731 timecode1.minutes = 0;
1732 timecode1.seconds = 0;
1733 timecode1.frames = 0;
1734 timecode1.subframes = 0;
1735 sample1 = oldsample = 0;
1736 sample_increment = session->frame_rate();
1738 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1739 cout << "Starting at sample: " << sample1 << " -> ";
1740 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1742 for (int i = 0; i < 3600; i++) {
1743 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1744 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1746 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1747 // cout << "sample: " << sample1 << endl;
1748 // cout << "sample: " << sample1 << " -> ";
1749 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1751 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1753 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1757 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1758 cout << "ERROR: timecode2 not equal timecode1" << endl;
1759 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1760 cout << "sample: " << sample1 << endl;
1761 cout << "sample: " << sample1 << " -> ";
1762 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1765 oldsample = sample1;
1766 session->timecode_increment_seconds( timecode1 );
1769 cout << "sample_increment: " << sample_increment << endl;
1770 cout << "sample: " << sample1 << " -> ";
1771 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1775 #ifdef Timecode_SAMPLE_TEST_6
1776 // Test 6: use_offset = true, use_subframes = false, increment minutes
1777 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1779 timecode1.hours = 0;
1780 timecode1.minutes = 0;
1781 timecode1.seconds = 0;
1782 timecode1.frames = 0;
1783 timecode1.subframes = 0;
1784 sample1 = oldsample = 0;
1785 sample_increment = session->frame_rate() * 60;
1787 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1788 cout << "Starting at sample: " << sample1 << " -> ";
1789 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1791 for (int i = 0; i < 60; i++) {
1792 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1793 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1795 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1796 // cout << "sample: " << sample1 << endl;
1797 // cout << "sample: " << sample1 << " -> ";
1798 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1800 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1802 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1806 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1807 cout << "ERROR: timecode2 not equal timecode1" << endl;
1808 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1809 cout << "sample: " << sample1 << endl;
1810 cout << "sample: " << sample1 << " -> ";
1811 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1814 oldsample = sample1;
1815 session->timecode_increment_minutes( timecode1 );
1818 cout << "sample_increment: " << sample_increment << endl;
1819 cout << "sample: " << sample1 << " -> ";
1820 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1823 #ifdef Timecode_SAMPLE_TEST_7
1824 // Test 7: use_offset = true, use_subframes = false, increment hours
1825 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1827 timecode1.hours = 0;
1828 timecode1.minutes = 0;
1829 timecode1.seconds = 0;
1830 timecode1.frames = 0;
1831 timecode1.subframes = 0;
1832 sample1 = oldsample = 0;
1833 sample_increment = session->frame_rate() * 60 * 60;
1835 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1836 cout << "Starting at sample: " << sample1 << " -> ";
1837 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1839 for (int i = 0; i < 10; i++) {
1840 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1841 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1843 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1844 // cout << "sample: " << sample1 << endl;
1845 // cout << "sample: " << sample1 << " -> ";
1846 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1848 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1850 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1854 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1855 cout << "ERROR: timecode2 not equal timecode1" << endl;
1856 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1857 cout << "sample: " << sample1 << endl;
1858 cout << "sample: " << sample1 << " -> ";
1859 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1862 oldsample = sample1;
1863 session->timecode_increment_hours( timecode1 );
1866 cout << "sample_increment: " << sample_increment << endl;
1867 cout << "sample: " << sample1 << " -> ";
1868 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1877 AudioClock::minsec_frame_from_display () const
1883 int hrs = atoi (ms_hours_label.get_text());
1884 int mins = atoi (ms_minutes_label.get_text());
1885 float secs = atof (ms_seconds_label.get_text());
1887 nframes_t sr = session->frame_rate();
1889 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1893 AudioClock::bbt_frame_from_display (nframes_t pos) const
1896 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1901 any.type = AnyTime::BBT;
1903 any.bbt.bars = atoi (bars_label.get_text());
1904 any.bbt.beats = atoi (beats_label.get_text());
1905 any.bbt.ticks = atoi (ticks_label.get_text());
1912 nframes_t ret = session->convert_to_frames_at (pos, any);
1919 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1922 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1929 bbt.bars = atoi (bars_label.get_text());
1930 bbt.beats = atoi (beats_label.get_text());
1931 bbt.ticks = atoi (ticks_label.get_text());
1933 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1937 AudioClock::audio_frame_from_display () const
1939 return (nframes_t) atoi (audio_frames_label.get_text());
1943 AudioClock::build_ops_menu ()
1945 using namespace Menu_Helpers;
1946 ops_menu = new Menu;
1947 MenuList& ops_items = ops_menu->items();
1948 ops_menu->set_name ("ArdourContextMenu");
1950 if (!Profile->get_sae()) {
1951 ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), Timecode)));
1953 ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1954 ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1955 ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1956 ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1960 AudioClock::set_mode (Mode m)
1962 /* slightly tricky: this is called from within the ARDOUR_UI
1963 constructor by some of its clock members. at that time
1964 the instance pointer is unset, so we have to be careful.
1965 the main idea is to drop keyboard focus in case we had
1966 started editing the clock and then we switch clock mode.
1969 clock_base.grab_focus ();
1975 clock_base.remove ();
1981 clock_base.add (timecode_packer_hbox);
1985 clock_base.add (bbt_packer_hbox);
1989 clock_base.add (minsec_packer_hbox);
1993 clock_base.add (frames_packer_hbox);
1997 clock_base.add (off_hbox);
2001 set_size_requests ();
2003 set (last_when, true);
2004 clock_base.show_all ();
2005 key_entry_state = 0;
2007 if (!is_transient) {
2008 ModeChanged (); /* EMIT SIGNAL */
2009 mode_changed (); /* EMIT SIGNAL */
2014 AudioClock::set_size_requests ()
2016 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
2020 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
2021 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
2022 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
2023 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
2027 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
2028 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
2029 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
2033 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
2034 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
2035 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
2039 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
2043 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);
2050 AudioClock::set_bbt_reference (nframes64_t pos)
2052 bbt_reference_time = pos;