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 cerr << "button event on clock but we are dragging\n";
1112 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1114 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
1115 // we actually dragged so return without setting editing focus, or we shift clicked
1121 if (ops_menu == 0) {
1124 ops_menu->popup (1, ev->time);
1128 if (Keyboard::is_context_menu_event (ev)) {
1129 cerr << "Context menu event on clock\n";
1130 if (ops_menu == 0) {
1133 ops_menu->popup (1, ev->time);
1137 switch (ev->button) {
1140 case Timecode_Hours:
1141 hours_ebox.grab_focus();
1143 case Timecode_Minutes:
1144 minutes_ebox.grab_focus();
1146 case Timecode_Seconds:
1147 seconds_ebox.grab_focus();
1149 case Timecode_Frames:
1150 frames_ebox.grab_focus();
1154 audio_frames_ebox.grab_focus();
1158 ms_hours_ebox.grab_focus();
1161 ms_minutes_ebox.grab_focus();
1164 ms_seconds_ebox.grab_focus();
1168 bars_ebox.grab_focus ();
1171 beats_ebox.grab_focus ();
1174 ticks_ebox.grab_focus ();
1187 AudioClock::field_button_press_event (GdkEventButton *ev, Field /*field*/)
1193 nframes_t frames = 0;
1195 switch (ev->button) {
1197 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1199 ValueChanged (); /* EMIT_SIGNAL */
1202 /* make absolutely sure that the pointer is grabbed */
1203 gdk_pointer_grab(ev->window,false ,
1204 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1205 NULL,NULL,ev->time);
1208 drag_start_y = ev->y;
1213 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1215 ValueChanged (); /* EMIT_SIGNAL */
1220 /* used for context sensitive menu */
1233 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1239 nframes_t frames = 0;
1241 switch (ev->direction) {
1244 frames = get_frames (field);
1246 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1249 set (current_time() + frames, true);
1250 ValueChanged (); /* EMIT_SIGNAL */
1254 case GDK_SCROLL_DOWN:
1255 frames = get_frames (field);
1257 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1261 if ((double)current_time() - (double)frames < 0.0) {
1264 set (current_time() - frames, true);
1267 ValueChanged (); /* EMIT_SIGNAL */
1280 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1282 if (session == 0 || !dragging) {
1286 float pixel_frame_scale_factor = 0.2f;
1289 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1290 pixel_frame_scale_factor = 0.1f;
1294 if (Keyboard::modifier_state_contains (ev->state,
1295 Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) {
1297 pixel_frame_scale_factor = 0.025f;
1300 double y_delta = ev->y - drag_y;
1302 drag_accum += y_delta*pixel_frame_scale_factor;
1306 if (trunc(drag_accum) != 0) {
1311 dir = (drag_accum < 0 ? 1:-1);
1312 pos = current_time();
1313 frames = get_frames (field,pos,dir);
1315 if (frames != 0 && frames * drag_accum < current_time()) {
1317 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1325 ValueChanged(); /* EMIT_SIGNAL */
1334 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1337 nframes_t frames = 0;
1340 case Timecode_Hours:
1341 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1343 case Timecode_Minutes:
1344 frames = (nframes_t) floor (60.0 * session->frame_rate());
1346 case Timecode_Seconds:
1347 frames = session->frame_rate();
1349 case Timecode_Frames:
1350 frames = (nframes_t) floor (session->frame_rate() / session->timecode_frames_per_second());
1358 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1361 frames = (nframes_t) floor (60.0 * session->frame_rate());
1364 frames = session->frame_rate();
1371 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1377 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1383 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1391 AudioClock::current_time (nframes_t pos) const
1397 ret = timecode_frame_from_display ();
1400 ret = bbt_frame_from_display (pos);
1404 ret = minsec_frame_from_display ();
1408 ret = audio_frame_from_display ();
1419 AudioClock::current_duration (nframes_t pos) const
1425 ret = timecode_frame_from_display ();
1428 ret = bbt_frame_duration_from_display (pos);
1432 ret = minsec_frame_from_display ();
1436 ret = audio_frame_from_display ();
1447 AudioClock::timecode_sanitize_display()
1449 // Check Timecode fields for sanity, possibly adjusting values
1450 if (atoi(minutes_label.get_text()) > 59) {
1451 minutes_label.set_text("59");
1454 if (atoi(seconds_label.get_text()) > 59) {
1455 seconds_label.set_text("59");
1458 switch ((long)rint(session->timecode_frames_per_second())) {
1460 if (atoi(frames_label.get_text()) > 23) {
1461 frames_label.set_text("23");
1465 if (atoi(frames_label.get_text()) > 24) {
1466 frames_label.set_text("24");
1470 if (atoi(frames_label.get_text()) > 29) {
1471 frames_label.set_text("29");
1478 if (session->timecode_drop_frames()) {
1479 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1480 frames_label.set_text("02");
1486 AudioClock::timecode_frame_from_display () const
1492 Timecode::Time timecode;
1495 timecode.hours = atoi (hours_label.get_text());
1496 timecode.minutes = atoi (minutes_label.get_text());
1497 timecode.seconds = atoi (seconds_label.get_text());
1498 timecode.frames = atoi (frames_label.get_text());
1499 timecode.rate = session->timecode_frames_per_second();
1500 timecode.drop= session->timecode_drop_frames();
1502 session->timecode_to_sample( timecode, sample, false /* use_offset */, false /* use_subframes */ );
1506 #define Timecode_SAMPLE_TEST_1
1507 #define Timecode_SAMPLE_TEST_2
1508 #define Timecode_SAMPLE_TEST_3
1509 #define Timecode_SAMPLE_TEST_4
1510 #define Timecode_SAMPLE_TEST_5
1511 #define Timecode_SAMPLE_TEST_6
1512 #define Timecode_SAMPLE_TEST_7
1514 // Testcode for timecode<->sample conversions (P.S.)
1515 Timecode::Time timecode1;
1517 nframes_t oldsample = 0;
1518 Timecode::Time timecode2;
1519 nframes_t sample_increment;
1521 sample_increment = (long)rint(session->frame_rate() / session->timecode_frames_per_second);
1523 #ifdef Timecode_SAMPLE_TEST_1
1524 // Test 1: use_offset = false, use_subframes = false
1525 cout << "use_offset = false, use_subframes = false" << endl;
1526 for (int i = 0; i < 108003; i++) {
1527 session->timecode_to_sample( timecode1, sample1, false /* use_offset */, false /* use_subframes */ );
1528 session->sample_to_timecode( sample1, timecode2, false /* use_offset */, false /* use_subframes */ );
1530 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1531 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1532 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1533 cout << "sample: " << sample1 << endl;
1534 cout << "sample: " << sample1 << " -> ";
1535 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1539 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1540 cout << "ERROR: timecode2 not equal timecode1" << endl;
1541 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1542 cout << "sample: " << sample1 << endl;
1543 cout << "sample: " << sample1 << " -> ";
1544 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1547 oldsample = sample1;
1548 session->timecode_increment( timecode1 );
1551 cout << "sample_increment: " << sample_increment << endl;
1552 cout << "sample: " << sample1 << " -> ";
1553 cout << "timecode: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1556 #ifdef Timecode_SAMPLE_TEST_2
1557 // Test 2: use_offset = true, use_subframes = false
1558 cout << "use_offset = true, use_subframes = false" << endl;
1560 timecode1.hours = 0;
1561 timecode1.minutes = 0;
1562 timecode1.seconds = 0;
1563 timecode1.frames = 0;
1564 timecode1.subframes = 0;
1565 sample1 = oldsample = 0;
1567 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1568 cout << "Starting at sample: " << sample1 << " -> ";
1569 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1571 for (int i = 0; i < 108003; i++) {
1572 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1573 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1575 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1576 // cout << "sample: " << sample1 << endl;
1577 // cout << "sample: " << sample1 << " -> ";
1578 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1580 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1581 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1582 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1583 cout << "sample: " << sample1 << endl;
1584 cout << "sample: " << sample1 << " -> ";
1585 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1589 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1590 cout << "ERROR: timecode2 not equal timecode1" << endl;
1591 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1592 cout << "sample: " << sample1 << endl;
1593 cout << "sample: " << sample1 << " -> ";
1594 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1597 oldsample = sample1;
1598 session->timecode_increment( timecode1 );
1601 cout << "sample_increment: " << sample_increment << endl;
1602 cout << "sample: " << sample1 << " -> ";
1603 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1606 #ifdef Timecode_SAMPLE_TEST_3
1607 // Test 3: use_offset = true, use_subframes = false, decrement
1608 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1610 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1611 cout << "Starting at sample: " << sample1 << " -> ";
1612 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1614 for (int i = 0; i < 108003; i++) {
1615 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1616 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1618 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1619 // cout << "sample: " << sample1 << endl;
1620 // cout << "sample: " << sample1 << " -> ";
1621 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1623 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1624 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1625 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1626 cout << "sample: " << sample1 << endl;
1627 cout << "sample: " << sample1 << " -> ";
1628 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1632 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1633 cout << "ERROR: timecode2 not equal timecode1" << endl;
1634 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1635 cout << "sample: " << sample1 << endl;
1636 cout << "sample: " << sample1 << " -> ";
1637 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1640 oldsample = sample1;
1641 session->timecode_decrement( timecode1 );
1644 cout << "sample_decrement: " << sample_increment << endl;
1645 cout << "sample: " << sample1 << " -> ";
1646 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1650 #ifdef Timecode_SAMPLE_TEST_4
1651 // Test 4: use_offset = true, use_subframes = true
1652 cout << "use_offset = true, use_subframes = true" << endl;
1654 for (long sub = 5; sub < 80; sub += 5) {
1655 timecode1.hours = 0;
1656 timecode1.minutes = 0;
1657 timecode1.seconds = 0;
1658 timecode1.frames = 0;
1659 timecode1.subframes = 0;
1660 sample1 = oldsample = (sample_increment * sub) / 80;
1662 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, true /* use_subframes */ );
1664 cout << "starting at sample: " << sample1 << " -> ";
1665 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1667 for (int i = 0; i < 108003; i++) {
1668 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1669 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1671 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1672 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1673 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1674 cout << "sample: " << sample1 << endl;
1675 cout << "sample: " << sample1 << " -> ";
1676 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1680 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1681 cout << "ERROR: timecode2 not equal timecode1" << endl;
1682 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1683 cout << "sample: " << sample1 << endl;
1684 cout << "sample: " << sample1 << " -> ";
1685 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1688 oldsample = sample1;
1689 session->timecode_increment( timecode1 );
1692 cout << "sample_increment: " << sample_increment << endl;
1693 cout << "sample: " << sample1 << " -> ";
1694 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1696 for (int i = 0; i < 108003; i++) {
1697 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1698 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1700 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1701 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1702 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1703 cout << "sample: " << sample1 << endl;
1704 cout << "sample: " << sample1 << " -> ";
1705 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1709 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1710 cout << "ERROR: timecode2 not equal timecode1" << endl;
1711 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1712 cout << "sample: " << sample1 << endl;
1713 cout << "sample: " << sample1 << " -> ";
1714 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1717 oldsample = sample1;
1718 session->timecode_decrement( timecode1 );
1721 cout << "sample_decrement: " << sample_increment << endl;
1722 cout << "sample: " << sample1 << " -> ";
1723 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1728 #ifdef Timecode_SAMPLE_TEST_5
1729 // Test 5: use_offset = true, use_subframes = false, increment seconds
1730 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1732 timecode1.hours = 0;
1733 timecode1.minutes = 0;
1734 timecode1.seconds = 0;
1735 timecode1.frames = 0;
1736 timecode1.subframes = 0;
1737 sample1 = oldsample = 0;
1738 sample_increment = session->frame_rate();
1740 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1741 cout << "Starting at sample: " << sample1 << " -> ";
1742 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1744 for (int i = 0; i < 3600; i++) {
1745 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1746 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1748 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1749 // cout << "sample: " << sample1 << endl;
1750 // cout << "sample: " << sample1 << " -> ";
1751 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1753 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1755 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1759 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1760 cout << "ERROR: timecode2 not equal timecode1" << endl;
1761 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1762 cout << "sample: " << sample1 << endl;
1763 cout << "sample: " << sample1 << " -> ";
1764 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1767 oldsample = sample1;
1768 session->timecode_increment_seconds( timecode1 );
1771 cout << "sample_increment: " << sample_increment << endl;
1772 cout << "sample: " << sample1 << " -> ";
1773 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1777 #ifdef Timecode_SAMPLE_TEST_6
1778 // Test 6: use_offset = true, use_subframes = false, increment minutes
1779 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1781 timecode1.hours = 0;
1782 timecode1.minutes = 0;
1783 timecode1.seconds = 0;
1784 timecode1.frames = 0;
1785 timecode1.subframes = 0;
1786 sample1 = oldsample = 0;
1787 sample_increment = session->frame_rate() * 60;
1789 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1790 cout << "Starting at sample: " << sample1 << " -> ";
1791 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1793 for (int i = 0; i < 60; i++) {
1794 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1795 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1797 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1798 // cout << "sample: " << sample1 << endl;
1799 // cout << "sample: " << sample1 << " -> ";
1800 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1802 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1804 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1808 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1809 cout << "ERROR: timecode2 not equal timecode1" << endl;
1810 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1811 cout << "sample: " << sample1 << endl;
1812 cout << "sample: " << sample1 << " -> ";
1813 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1816 oldsample = sample1;
1817 session->timecode_increment_minutes( timecode1 );
1820 cout << "sample_increment: " << sample_increment << endl;
1821 cout << "sample: " << sample1 << " -> ";
1822 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1825 #ifdef Timecode_SAMPLE_TEST_7
1826 // Test 7: use_offset = true, use_subframes = false, increment hours
1827 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1829 timecode1.hours = 0;
1830 timecode1.minutes = 0;
1831 timecode1.seconds = 0;
1832 timecode1.frames = 0;
1833 timecode1.subframes = 0;
1834 sample1 = oldsample = 0;
1835 sample_increment = session->frame_rate() * 60 * 60;
1837 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1838 cout << "Starting at sample: " << sample1 << " -> ";
1839 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1841 for (int i = 0; i < 10; i++) {
1842 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1843 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1845 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1846 // cout << "sample: " << sample1 << endl;
1847 // cout << "sample: " << sample1 << " -> ";
1848 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1850 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1852 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1856 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1857 cout << "ERROR: timecode2 not equal timecode1" << endl;
1858 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1859 cout << "sample: " << sample1 << endl;
1860 cout << "sample: " << sample1 << " -> ";
1861 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1864 oldsample = sample1;
1865 session->timecode_increment_hours( timecode1 );
1868 cout << "sample_increment: " << sample_increment << endl;
1869 cout << "sample: " << sample1 << " -> ";
1870 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1879 AudioClock::minsec_frame_from_display () const
1885 int hrs = atoi (ms_hours_label.get_text());
1886 int mins = atoi (ms_minutes_label.get_text());
1887 float secs = atof (ms_seconds_label.get_text());
1889 nframes_t sr = session->frame_rate();
1891 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1895 AudioClock::bbt_frame_from_display (nframes_t pos) const
1898 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1903 any.type = AnyTime::BBT;
1905 any.bbt.bars = atoi (bars_label.get_text());
1906 any.bbt.beats = atoi (beats_label.get_text());
1907 any.bbt.ticks = atoi (ticks_label.get_text());
1914 nframes_t ret = session->convert_to_frames_at (pos, any);
1921 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1924 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1931 bbt.bars = atoi (bars_label.get_text());
1932 bbt.beats = atoi (beats_label.get_text());
1933 bbt.ticks = atoi (ticks_label.get_text());
1935 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1939 AudioClock::audio_frame_from_display () const
1941 return (nframes_t) atoi (audio_frames_label.get_text());
1945 AudioClock::build_ops_menu ()
1947 using namespace Menu_Helpers;
1948 ops_menu = new Menu;
1949 MenuList& ops_items = ops_menu->items();
1950 ops_menu->set_name ("ArdourContextMenu");
1952 if (!Profile->get_sae()) {
1953 ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), Timecode)));
1955 ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1956 ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1957 ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1958 ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1960 if (editable && !is_duration) {
1961 ops_items.push_back (SeparatorElem());
1962 ops_items.push_back (MenuElem (_("Set From Playhead"), mem_fun(*this, &AudioClock::set_from_playhead)));
1963 ops_items.push_back (MenuElem (_("Locate to this time"), mem_fun(*this, &AudioClock::locate)));
1968 AudioClock::set_from_playhead ()
1974 set (session->transport_frame());
1978 AudioClock::locate ()
1980 if (!session || is_duration) {
1984 session->request_locate (current_time(), false);
1988 AudioClock::set_mode (Mode m)
1990 /* slightly tricky: this is called from within the ARDOUR_UI
1991 constructor by some of its clock members. at that time
1992 the instance pointer is unset, so we have to be careful.
1993 the main idea is to drop keyboard focus in case we had
1994 started editing the clock and then we switch clock mode.
1997 clock_base.grab_focus ();
2003 clock_base.remove ();
2009 clock_base.add (timecode_packer_hbox);
2013 clock_base.add (bbt_packer_hbox);
2017 clock_base.add (minsec_packer_hbox);
2021 clock_base.add (frames_packer_hbox);
2025 clock_base.add (off_hbox);
2029 set_size_requests ();
2031 set (last_when, true);
2032 clock_base.show_all ();
2033 key_entry_state = 0;
2035 if (!is_transient) {
2036 ModeChanged (); /* EMIT SIGNAL */
2037 mode_changed (); /* EMIT SIGNAL */
2042 AudioClock::set_size_requests ()
2044 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
2048 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
2049 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
2050 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
2051 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
2055 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
2056 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
2057 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
2061 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
2062 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
2063 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
2067 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
2071 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);
2078 AudioClock::set_bbt_reference (nframes64_t pos)
2080 bbt_reference_time = pos;