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 <sigc++/bind.h>
33 #include "ardour_ui.h"
34 #include "audio_clock.h"
39 using namespace ARDOUR;
48 sigc::signal<void> AudioClock::ModeChanged;
49 vector<AudioClock*> AudioClock::clocks;
51 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
53 2, /* SMPTE_Minutes */
54 2, /* SMPTE_Seconds */
65 AudioClock::AudioClock (std::string clock_name, bool transient, std::string widget_name, bool allow_edit, bool duration, bool with_info)
67 is_transient (transient),
68 is_duration (duration),
69 editable (allow_edit),
87 frames_upper_info_label = manage (new Label);
88 frames_lower_info_label = manage (new Label);
89 smpte_upper_info_label = manage (new Label);
90 smpte_lower_info_label = manage (new Label);
91 bbt_upper_info_label = manage (new Label);
92 bbt_lower_info_label = manage (new Label);
94 frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
95 frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
96 smpte_upper_info_label->set_name ("AudioClockSMPTEUpperInfo");
97 smpte_lower_info_label->set_name ("AudioClockSMPTELowerInfo");
98 bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
99 bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
101 Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0);
102 Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0);
104 frames_info_box.pack_start (*frames_upper_info_label, true, true);
105 frames_info_box.pack_start (*frames_lower_info_label, true, true);
106 smpte_info_box.pack_start (*smpte_upper_info_label, true, true);
107 smpte_info_box.pack_start (*smpte_lower_info_label, true, true);
108 bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
109 bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
112 frames_upper_info_label = 0;
113 frames_lower_info_label = 0;
114 smpte_upper_info_label = 0;
115 smpte_lower_info_label = 0;
116 bbt_upper_info_label = 0;
117 bbt_lower_info_label = 0;
120 audio_frames_ebox.add (audio_frames_label);
122 frames_packer.set_homogeneous (false);
123 frames_packer.set_border_width (2);
124 frames_packer.pack_start (audio_frames_ebox, false, false);
127 frames_packer.pack_start (frames_info_box, false, false, 5);
130 frames_packer_hbox.pack_start (frames_packer, true, false);
132 hours_ebox.add (hours_label);
133 minutes_ebox.add (minutes_label);
134 seconds_ebox.add (seconds_label);
135 frames_ebox.add (frames_label);
136 bars_ebox.add (bars_label);
137 beats_ebox.add (beats_label);
138 ticks_ebox.add (ticks_label);
139 ms_hours_ebox.add (ms_hours_label);
140 ms_minutes_ebox.add (ms_minutes_label);
141 ms_seconds_ebox.add (ms_seconds_label);
143 smpte_packer.set_homogeneous (false);
144 smpte_packer.set_border_width (2);
145 smpte_packer.pack_start (hours_ebox, false, false);
146 smpte_packer.pack_start (colon1, false, false);
147 smpte_packer.pack_start (minutes_ebox, false, false);
148 smpte_packer.pack_start (colon2, false, false);
149 smpte_packer.pack_start (seconds_ebox, false, false);
150 smpte_packer.pack_start (colon3, false, false);
151 smpte_packer.pack_start (frames_ebox, false, false);
154 smpte_packer.pack_start (smpte_info_box, false, false, 5);
157 smpte_packer_hbox.pack_start (smpte_packer, true, false);
159 bbt_packer.set_homogeneous (false);
160 bbt_packer.set_border_width (2);
161 bbt_packer.pack_start (bars_ebox, false, false);
162 bbt_packer.pack_start (b1, false, false);
163 bbt_packer.pack_start (beats_ebox, false, false);
164 bbt_packer.pack_start (b2, false, false);
165 bbt_packer.pack_start (ticks_ebox, false, false);
168 bbt_packer.pack_start (bbt_info_box, false, false, 5);
171 bbt_packer_hbox.pack_start (bbt_packer, true, false);
173 minsec_packer.set_homogeneous (false);
174 minsec_packer.set_border_width (2);
175 minsec_packer.pack_start (ms_hours_ebox, false, false);
176 minsec_packer.pack_start (colon4, false, false);
177 minsec_packer.pack_start (ms_minutes_ebox, false, false);
178 minsec_packer.pack_start (colon5, false, false);
179 minsec_packer.pack_start (ms_seconds_ebox, false, false);
181 minsec_packer_hbox.pack_start (minsec_packer, true, false);
183 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
184 clock_frame.set_name ("BaseFrame");
186 clock_frame.add (clock_base);
188 set_widget_name (widget_name);
190 _mode = BBT; /* lie to force mode switch */
193 pack_start (clock_frame, true, true);
195 /* the clock base handles button releases for menu popup regardless of
196 editable status. if the clock is editable, the clock base is where
197 we pass focus to after leaving the last editable "field", which
198 will then shutdown editing till the user starts it up again.
200 it does this because the focus out event on the field disables
201 keyboard event handling, and we don't connect anything up to
202 notice focus in on the clock base. hence, keyboard event handling
206 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
207 clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
209 Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
215 set (last_when, true);
218 clocks.push_back (this);
223 AudioClock::set_widget_name (string name)
225 Widget::set_name (name);
227 clock_base.set_name (name);
229 audio_frames_label.set_name (name);
230 hours_label.set_name (name);
231 minutes_label.set_name (name);
232 seconds_label.set_name (name);
233 frames_label.set_name (name);
234 bars_label.set_name (name);
235 beats_label.set_name (name);
236 ticks_label.set_name (name);
237 ms_hours_label.set_name (name);
238 ms_minutes_label.set_name (name);
239 ms_seconds_label.set_name (name);
240 hours_ebox.set_name (name);
241 minutes_ebox.set_name (name);
242 seconds_ebox.set_name (name);
243 frames_ebox.set_name (name);
244 audio_frames_ebox.set_name (name);
245 bars_ebox.set_name (name);
246 beats_ebox.set_name (name);
247 ticks_ebox.set_name (name);
248 ms_hours_ebox.set_name (name);
249 ms_minutes_ebox.set_name (name);
250 ms_seconds_ebox.set_name (name);
252 colon1.set_name (name);
253 colon2.set_name (name);
254 colon3.set_name (name);
255 colon4.set_name (name);
256 colon5.set_name (name);
264 AudioClock::setup_events ()
266 clock_base.set_flags (Gtk::CAN_FOCUS);
268 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);
269 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);
270 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);
271 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);
272 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);
273 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);
274 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);
275 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);
276 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);
277 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);
278 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);
280 hours_ebox.set_flags (Gtk::CAN_FOCUS);
281 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
282 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
283 frames_ebox.set_flags (Gtk::CAN_FOCUS);
284 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
285 bars_ebox.set_flags (Gtk::CAN_FOCUS);
286 beats_ebox.set_flags (Gtk::CAN_FOCUS);
287 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
288 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
289 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
290 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
292 hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
293 minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
294 seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
295 frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
296 audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
297 bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
298 beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
299 ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
300 ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
301 ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
302 ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
304 hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Hours));
305 minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
306 seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
307 frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Frames));
308 audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
309 bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
310 beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
311 ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
312 ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
313 ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
314 ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
316 hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Hours));
317 minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
318 seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
319 frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Frames));
320 audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
321 bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
322 beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
323 ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
324 ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
325 ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
326 ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
328 hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Hours));
329 minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Minutes));
330 seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Seconds));
331 frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Frames));
332 audio_frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
333 bars_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
334 beats_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
335 ticks_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
336 ms_hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
337 ms_minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
338 ms_seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
340 hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Hours));
341 minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Minutes));
342 seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Seconds));
343 frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Frames));
344 audio_frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), AudioFrames));
345 bars_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Bars));
346 beats_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Beats));
347 ticks_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Ticks));
348 ms_hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Hours));
349 ms_minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Minutes));
350 ms_seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Seconds));
352 hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours));
353 minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
354 seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
355 frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Frames));
356 audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
357 bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
358 beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
359 ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
360 ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
361 ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
362 ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
364 hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
365 minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
366 seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
367 frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
368 audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
369 bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
370 beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
371 ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
372 ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
373 ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
374 ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
376 hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
377 minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
378 seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
379 frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
380 audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
381 bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
382 beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
383 ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
384 ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
385 ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
386 ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
388 clock_base.signal_focus_in_event().connect (mem_fun (*this, &AudioClock::drop_focus_handler));
392 AudioClock::drop_focus_handler (GdkEventFocus* ignored)
394 Keyboard::magic_widget_drop_focus ();
399 AudioClock::on_realize ()
403 /* styles are not available until the widgets are bound to a window */
405 set_size_requests ();
409 AudioClock::set (nframes_t when, bool force, nframes_t offset, int which)
412 if ((!force && !is_visible()) || session == 0) {
416 if (when == last_when && !offset && !force) {
420 bool pdelta = Config->get_primary_clock_delta_edit_cursor();
421 bool sdelta = Config->get_secondary_clock_delta_edit_cursor();
423 if (offset && which == 1 && pdelta) {
424 when = (when > offset) ? when - offset : offset - when;
425 } else if (offset && which == 2 && sdelta) {
426 when = (when > offset) ? when - offset : offset - when;
429 if (which == 1 && pdelta && !last_pdelta) {
430 cout << "set_widget_name() called" << endl;
431 set_widget_name("TransportClockDisplayDelta");
433 } else if (which == 1 && !pdelta && last_pdelta) {
434 set_widget_name("TransportClockDisplay");
436 } else if (which == 2 && sdelta && !last_sdelta) {
437 set_widget_name("SecondaryClockDisplayDelta");
439 } else if (which == 2 && !sdelta && last_sdelta) {
440 set_widget_name("SecondaryClockDisplay");
446 set_smpte (when, force);
450 set_bbt (when, force);
454 set_minsec (when, force);
458 set_frames (when, force);
469 AudioClock::smpte_offset_changed ()
476 current = current_duration();
478 current = current_time ();
488 AudioClock::set_frames (nframes_t when, bool force)
491 snprintf (buf, sizeof (buf), "%u", when);
492 audio_frames_label.set_text (buf);
494 if (frames_upper_info_label) {
495 nframes_t rate = session->frame_rate();
497 if (fmod (rate, 1000.0) == 0.000) {
498 sprintf (buf, "%uK", rate/1000);
500 sprintf (buf, "%.3fK", rate/1000.0f);
503 frames_upper_info_label->set_text (buf);
505 float vid_pullup = Config->get_video_pullup();
507 if (vid_pullup == 0.0) {
508 frames_lower_info_label->set_text(_("none"));
510 sprintf (buf, "%-6.4f", vid_pullup);
511 frames_lower_info_label->set_text (buf);
517 AudioClock::set_minsec (nframes_t when, bool force)
526 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
527 left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
528 mins = (int) floor (left / (session->frame_rate() * 60.0f));
529 left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
530 secs = left / (float) session->frame_rate();
532 if (force || hrs != ms_last_hrs) {
533 sprintf (buf, "%02d", hrs);
534 ms_hours_label.set_text (buf);
538 if (force || mins != ms_last_mins) {
539 sprintf (buf, "%02d", mins);
540 ms_minutes_label.set_text (buf);
544 if (force || secs != ms_last_secs) {
545 sprintf (buf, "%06.3f", secs);
546 ms_seconds_label.set_text (buf);
552 AudioClock::set_smpte (nframes_t when, bool force)
558 session->smpte_duration (when, smpte);
560 session->smpte_time (when, smpte);
563 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
564 if (smpte.negative) {
565 sprintf (buf, "-%02" PRIu32, smpte.hours);
567 sprintf (buf, " %02" PRIu32, smpte.hours);
569 hours_label.set_text (buf);
570 last_hrs = smpte.hours;
571 last_negative = smpte.negative;
574 if (force || smpte.minutes != last_mins) {
575 sprintf (buf, "%02" PRIu32, smpte.minutes);
576 minutes_label.set_text (buf);
577 last_mins = smpte.minutes;
580 if (force || smpte.seconds != last_secs) {
581 sprintf (buf, "%02" PRIu32, smpte.seconds);
582 seconds_label.set_text (buf);
583 last_secs = smpte.seconds;
586 if (force || smpte.frames != last_frames) {
587 sprintf (buf, "%02" PRIu32, smpte.frames);
588 frames_label.set_text (buf);
589 last_frames = smpte.frames;
592 if (smpte_upper_info_label) {
593 double smpte_frames = session->smpte_frames_per_second();
595 if ( fmod(smpte_frames, 1.0) == 0.0) {
596 sprintf (buf, "%u", int (smpte_frames));
598 sprintf (buf, "%.2f", smpte_frames);
601 smpte_upper_info_label->set_text (buf);
603 if (session->smpte_drop_frames()) {
606 sprintf (buf, "NDF");
609 smpte_lower_info_label->set_text (buf);
614 AudioClock::set_bbt (nframes_t when, bool force)
619 session->tempo_map().bbt_time (when, bbt);
620 sprintf (buf, "%03" PRIu32, bbt.bars);
621 bars_label.set_text (buf);
622 sprintf (buf, "%02" PRIu32, bbt.beats);
623 beats_label.set_text (buf);
624 sprintf (buf, "%04" PRIu32, bbt.ticks);
625 ticks_label.set_text (buf);
627 if (bbt_upper_info_label) {
628 TempoMap::Metric m (session->tempo_map().metric_at (when));
629 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
630 bbt_lower_info_label->set_text (buf);
631 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
632 bbt_upper_info_label->set_text (buf);
637 AudioClock::set_session (Session *s)
644 XMLNode* node = session->extra_xml (X_("ClockModes"));
645 AudioClock::Mode amode;
648 if ((prop = node->property (_name)) != 0) {
649 amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
654 set (last_when, true);
663 hours_ebox.grab_focus ();
667 bars_ebox.grab_focus ();
671 ms_hours_ebox.grab_focus ();
675 frames_ebox.grab_focus ();
685 AudioClock::field_key_press_event (GdkEventKey *ev, Field field)
687 /* all key activity is handled on key release */
692 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
697 bool move_on = false;
701 label = &hours_label;
704 label = &minutes_label;
707 label = &seconds_label;
710 label = &frames_label;
714 label = &audio_frames_label;
718 label = &ms_hours_label;
721 label = &ms_minutes_label;
724 label = &ms_seconds_label;
731 label = &beats_label;
734 label = &ticks_label;
740 switch (ev->keyval) {
784 if (_mode == MinSec && field == MS_Seconds) {
798 clock_base.grab_focus ();
807 if (key_entry_state == 0) {
809 /* initialize with a fresh new string */
811 if (field != AudioFrames) {
812 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
821 string existing = label->get_text();
822 if (existing.length() >= field_length[field]) {
823 new_text = existing.substr (1, field_length[field] - 1);
825 new_text = existing.substr (0, field_length[field] - 1);
829 new_text += new_char;
830 label->set_text (new_text);
834 if (key_entry_state == field_length[field]) {
840 if (key_entry_state) {
847 // Check SMPTE fields for sanity (may also adjust fields)
848 smpte_sanitize_display();
853 // Bars or beats should never be 0
854 if (atoi(bars_label.get_text()) == 0) {
855 bars_label.set_text("001");
857 if (atoi(beats_label.get_text()) == 0) {
858 beats_label.set_text("01");
865 ValueChanged(); /* EMIT_SIGNAL */
868 /* move on to the next field.
876 minutes_ebox.grab_focus ();
879 seconds_ebox.grab_focus ();
882 frames_ebox.grab_focus ();
885 clock_base.grab_focus ();
890 clock_base.grab_focus ();
896 ms_minutes_ebox.grab_focus ();
899 ms_seconds_ebox.grab_focus ();
902 clock_base.grab_focus ();
908 beats_ebox.grab_focus ();
911 ticks_ebox.grab_focus ();
914 clock_base.grab_focus ();
927 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
931 Keyboard::magic_widget_grab_focus ();
935 hours_ebox.set_flags (Gtk::HAS_FOCUS);
936 hours_ebox.set_state (Gtk::STATE_ACTIVE);
939 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
940 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
943 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
944 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
947 frames_ebox.set_flags (Gtk::HAS_FOCUS);
948 frames_ebox.set_state (Gtk::STATE_ACTIVE);
952 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
953 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
957 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
958 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
961 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
962 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
965 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
966 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
969 bars_ebox.set_flags (Gtk::HAS_FOCUS);
970 bars_ebox.set_state (Gtk::STATE_ACTIVE);
973 beats_ebox.set_flags (Gtk::HAS_FOCUS);
974 beats_ebox.set_state (Gtk::STATE_ACTIVE);
977 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
978 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
986 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
991 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
992 hours_ebox.set_state (Gtk::STATE_NORMAL);
995 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
996 minutes_ebox.set_state (Gtk::STATE_NORMAL);
999 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1000 seconds_ebox.set_state (Gtk::STATE_NORMAL);
1003 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1004 frames_ebox.set_state (Gtk::STATE_NORMAL);
1008 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1009 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
1013 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1014 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
1017 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1018 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
1021 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1022 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1026 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1027 bars_ebox.set_state (Gtk::STATE_NORMAL);
1030 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1031 beats_ebox.set_state (Gtk::STATE_NORMAL);
1034 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1035 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1039 Keyboard::magic_widget_drop_focus ();
1045 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1048 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1050 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
1051 // we actually dragged so return without setting editing focus, or we shift clicked
1057 if (ops_menu == 0) {
1060 ops_menu->popup (1, ev->time);
1064 if (Keyboard::is_context_menu_event (ev)) {
1065 if (ops_menu == 0) {
1068 ops_menu->popup (1, ev->time);
1072 switch (ev->button) {
1076 hours_ebox.grab_focus();
1079 minutes_ebox.grab_focus();
1082 seconds_ebox.grab_focus();
1085 frames_ebox.grab_focus();
1089 audio_frames_ebox.grab_focus();
1093 ms_hours_ebox.grab_focus();
1096 ms_minutes_ebox.grab_focus();
1099 ms_seconds_ebox.grab_focus();
1103 bars_ebox.grab_focus ();
1106 beats_ebox.grab_focus ();
1109 ticks_ebox.grab_focus ();
1122 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
1124 if (session == 0) return false;
1126 nframes_t frames = 0;
1128 switch (ev->button) {
1130 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1132 ValueChanged (); /* EMIT_SIGNAL */
1135 /* make absolutely sure that the pointer is grabbed */
1136 gdk_pointer_grab(ev->window,false ,
1137 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1138 NULL,NULL,ev->time);
1141 drag_start_y = ev->y;
1146 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1148 ValueChanged (); /* EMIT_SIGNAL */
1153 /* used for context sensitive menu */
1166 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1172 nframes_t frames = 0;
1174 switch (ev->direction) {
1177 frames = get_frames (field);
1179 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1182 set (current_time() + frames, true);
1183 ValueChanged (); /* EMIT_SIGNAL */
1187 case GDK_SCROLL_DOWN:
1188 frames = get_frames (field);
1190 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1194 if ((double)current_time() - (double)frames < 0.0) {
1197 set (current_time() - frames, true);
1200 ValueChanged (); /* EMIT_SIGNAL */
1213 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1215 if (session == 0 || !dragging) {
1219 float pixel_frame_scale_factor = 0.2f;
1222 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1223 pixel_frame_scale_factor = 0.1f;
1227 if (Keyboard::modifier_state_contains (ev->state,
1228 Keyboard::Control|Keyboard::Alt)) {
1230 pixel_frame_scale_factor = 0.025f;
1233 double y_delta = ev->y - drag_y;
1235 drag_accum += y_delta*pixel_frame_scale_factor;
1239 if (trunc(drag_accum) != 0) {
1244 dir = (drag_accum < 0 ? 1:-1);
1245 pos = current_time();
1246 frames = get_frames (field,pos,dir);
1248 if (frames != 0 && frames * drag_accum < current_time()) {
1250 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1258 ValueChanged(); /* EMIT_SIGNAL */
1267 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1270 nframes_t frames = 0;
1274 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1277 frames = (nframes_t) floor (60.0 * session->frame_rate());
1280 frames = session->frame_rate();
1283 frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second());
1291 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1294 frames = (nframes_t) floor (60.0 * session->frame_rate());
1297 frames = session->frame_rate();
1304 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1310 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1316 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1324 AudioClock::current_time (nframes_t pos) const
1330 ret = smpte_frame_from_display ();
1333 ret = bbt_frame_from_display (pos);
1337 ret = minsec_frame_from_display ();
1341 ret = audio_frame_from_display ();
1352 AudioClock::current_duration (nframes_t pos) const
1358 ret = smpte_frame_from_display ();
1361 ret = bbt_frame_duration_from_display (pos);
1365 ret = minsec_frame_from_display ();
1369 ret = audio_frame_from_display ();
1380 AudioClock::smpte_sanitize_display()
1382 // Check SMPTE fields for sanity, possibly adjusting values
1383 if (atoi(minutes_label.get_text()) > 59) {
1384 minutes_label.set_text("59");
1387 if (atoi(seconds_label.get_text()) > 59) {
1388 seconds_label.set_text("59");
1391 switch ((long)rint(session->smpte_frames_per_second())) {
1393 if (atoi(frames_label.get_text()) > 23) {
1394 frames_label.set_text("23");
1398 if (atoi(frames_label.get_text()) > 24) {
1399 frames_label.set_text("24");
1403 if (atoi(frames_label.get_text()) > 29) {
1404 frames_label.set_text("29");
1411 if (session->smpte_drop_frames()) {
1412 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1413 frames_label.set_text("02");
1419 AudioClock::smpte_frame_from_display () const
1428 smpte.hours = atoi (hours_label.get_text());
1429 smpte.minutes = atoi (minutes_label.get_text());
1430 smpte.seconds = atoi (seconds_label.get_text());
1431 smpte.frames = atoi (frames_label.get_text());
1432 smpte.rate = session->smpte_frames_per_second();
1433 smpte.drop= session->smpte_drop_frames();
1435 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1439 #define SMPTE_SAMPLE_TEST_1
1440 #define SMPTE_SAMPLE_TEST_2
1441 #define SMPTE_SAMPLE_TEST_3
1442 #define SMPTE_SAMPLE_TEST_4
1443 #define SMPTE_SAMPLE_TEST_5
1444 #define SMPTE_SAMPLE_TEST_6
1445 #define SMPTE_SAMPLE_TEST_7
1447 // Testcode for smpte<->sample conversions (P.S.)
1450 nframes_t oldsample = 0;
1452 nframes_t sample_increment;
1454 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1456 #ifdef SMPTE_SAMPLE_TEST_1
1457 // Test 1: use_offset = false, use_subframes = false
1458 cout << "use_offset = false, use_subframes = false" << endl;
1459 for (int i = 0; i < 108003; i++) {
1460 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1461 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1463 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1464 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1465 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1466 cout << "sample: " << sample1 << endl;
1467 cout << "sample: " << sample1 << " -> ";
1468 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1472 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1473 cout << "ERROR: smpte2 not equal smpte1" << endl;
1474 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1475 cout << "sample: " << sample1 << endl;
1476 cout << "sample: " << sample1 << " -> ";
1477 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1480 oldsample = sample1;
1481 session->smpte_increment( smpte1 );
1484 cout << "sample_increment: " << sample_increment << endl;
1485 cout << "sample: " << sample1 << " -> ";
1486 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1489 #ifdef SMPTE_SAMPLE_TEST_2
1490 // Test 2: use_offset = true, use_subframes = false
1491 cout << "use_offset = true, use_subframes = false" << endl;
1497 smpte1.subframes = 0;
1498 sample1 = oldsample = 0;
1500 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1501 cout << "Starting at sample: " << sample1 << " -> ";
1502 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1504 for (int i = 0; i < 108003; i++) {
1505 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1506 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1508 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1509 // cout << "sample: " << sample1 << endl;
1510 // cout << "sample: " << sample1 << " -> ";
1511 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1513 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1514 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1515 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1516 cout << "sample: " << sample1 << endl;
1517 cout << "sample: " << sample1 << " -> ";
1518 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1522 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1523 cout << "ERROR: smpte2 not equal smpte1" << endl;
1524 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1525 cout << "sample: " << sample1 << endl;
1526 cout << "sample: " << sample1 << " -> ";
1527 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1530 oldsample = sample1;
1531 session->smpte_increment( smpte1 );
1534 cout << "sample_increment: " << sample_increment << endl;
1535 cout << "sample: " << sample1 << " -> ";
1536 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1539 #ifdef SMPTE_SAMPLE_TEST_3
1540 // Test 3: use_offset = true, use_subframes = false, decrement
1541 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1543 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1544 cout << "Starting at sample: " << sample1 << " -> ";
1545 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1547 for (int i = 0; i < 108003; i++) {
1548 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1549 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1551 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1552 // cout << "sample: " << sample1 << endl;
1553 // cout << "sample: " << sample1 << " -> ";
1554 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1556 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1557 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1558 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1559 cout << "sample: " << sample1 << endl;
1560 cout << "sample: " << sample1 << " -> ";
1561 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1565 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1566 cout << "ERROR: smpte2 not equal smpte1" << endl;
1567 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1568 cout << "sample: " << sample1 << endl;
1569 cout << "sample: " << sample1 << " -> ";
1570 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1573 oldsample = sample1;
1574 session->smpte_decrement( smpte1 );
1577 cout << "sample_decrement: " << sample_increment << endl;
1578 cout << "sample: " << sample1 << " -> ";
1579 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1583 #ifdef SMPTE_SAMPLE_TEST_4
1584 // Test 4: use_offset = true, use_subframes = true
1585 cout << "use_offset = true, use_subframes = true" << endl;
1587 for (long sub = 5; sub < 80; sub += 5) {
1592 smpte1.subframes = 0;
1593 sample1 = oldsample = (sample_increment * sub) / 80;
1595 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1597 cout << "starting at sample: " << sample1 << " -> ";
1598 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1600 for (int i = 0; i < 108003; i++) {
1601 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1602 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1604 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1605 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1606 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1607 cout << "sample: " << sample1 << endl;
1608 cout << "sample: " << sample1 << " -> ";
1609 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1613 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1614 cout << "ERROR: smpte2 not equal smpte1" << endl;
1615 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1616 cout << "sample: " << sample1 << endl;
1617 cout << "sample: " << sample1 << " -> ";
1618 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1621 oldsample = sample1;
1622 session->smpte_increment( smpte1 );
1625 cout << "sample_increment: " << sample_increment << endl;
1626 cout << "sample: " << sample1 << " -> ";
1627 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1629 for (int i = 0; i < 108003; i++) {
1630 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1631 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1633 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1634 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1635 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1636 cout << "sample: " << sample1 << endl;
1637 cout << "sample: " << sample1 << " -> ";
1638 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1642 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1643 cout << "ERROR: smpte2 not equal smpte1" << endl;
1644 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1645 cout << "sample: " << sample1 << endl;
1646 cout << "sample: " << sample1 << " -> ";
1647 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1650 oldsample = sample1;
1651 session->smpte_decrement( smpte1 );
1654 cout << "sample_decrement: " << sample_increment << endl;
1655 cout << "sample: " << sample1 << " -> ";
1656 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1661 #ifdef SMPTE_SAMPLE_TEST_5
1662 // Test 5: use_offset = true, use_subframes = false, increment seconds
1663 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1669 smpte1.subframes = 0;
1670 sample1 = oldsample = 0;
1671 sample_increment = session->frame_rate();
1673 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1674 cout << "Starting at sample: " << sample1 << " -> ";
1675 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1677 for (int i = 0; i < 3600; i++) {
1678 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1679 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1681 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1682 // cout << "sample: " << sample1 << endl;
1683 // cout << "sample: " << sample1 << " -> ";
1684 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1686 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1688 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1692 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1693 cout << "ERROR: smpte2 not equal smpte1" << endl;
1694 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1695 cout << "sample: " << sample1 << endl;
1696 cout << "sample: " << sample1 << " -> ";
1697 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1700 oldsample = sample1;
1701 session->smpte_increment_seconds( smpte1 );
1704 cout << "sample_increment: " << sample_increment << endl;
1705 cout << "sample: " << sample1 << " -> ";
1706 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1710 #ifdef SMPTE_SAMPLE_TEST_6
1711 // Test 6: use_offset = true, use_subframes = false, increment minutes
1712 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1718 smpte1.subframes = 0;
1719 sample1 = oldsample = 0;
1720 sample_increment = session->frame_rate() * 60;
1722 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1723 cout << "Starting at sample: " << sample1 << " -> ";
1724 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1726 for (int i = 0; i < 60; i++) {
1727 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1728 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1730 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1731 // cout << "sample: " << sample1 << endl;
1732 // cout << "sample: " << sample1 << " -> ";
1733 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1735 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1737 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1741 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1742 cout << "ERROR: smpte2 not equal smpte1" << endl;
1743 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1744 cout << "sample: " << sample1 << endl;
1745 cout << "sample: " << sample1 << " -> ";
1746 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1749 oldsample = sample1;
1750 session->smpte_increment_minutes( smpte1 );
1753 cout << "sample_increment: " << sample_increment << endl;
1754 cout << "sample: " << sample1 << " -> ";
1755 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1758 #ifdef SMPTE_SAMPLE_TEST_7
1759 // Test 7: use_offset = true, use_subframes = false, increment hours
1760 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1766 smpte1.subframes = 0;
1767 sample1 = oldsample = 0;
1768 sample_increment = session->frame_rate() * 60 * 60;
1770 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1771 cout << "Starting at sample: " << sample1 << " -> ";
1772 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1774 for (int i = 0; i < 10; i++) {
1775 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1776 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1778 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1779 // cout << "sample: " << sample1 << endl;
1780 // cout << "sample: " << sample1 << " -> ";
1781 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1783 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1785 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1789 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1790 cout << "ERROR: smpte2 not equal smpte1" << endl;
1791 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1792 cout << "sample: " << sample1 << endl;
1793 cout << "sample: " << sample1 << " -> ";
1794 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1797 oldsample = sample1;
1798 session->smpte_increment_hours( smpte1 );
1801 cout << "sample_increment: " << sample_increment << endl;
1802 cout << "sample: " << sample1 << " -> ";
1803 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1812 AudioClock::minsec_frame_from_display () const
1818 int hrs = atoi (ms_hours_label.get_text());
1819 int mins = atoi (ms_minutes_label.get_text());
1820 float secs = atof (ms_seconds_label.get_text());
1822 nframes_t sr = session->frame_rate();
1824 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1828 AudioClock::bbt_frame_from_display (nframes_t pos) const
1831 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1836 any.type = AnyTime::BBT;
1838 any.bbt.bars = atoi (bars_label.get_text());
1839 any.bbt.beats = atoi (beats_label.get_text());
1840 any.bbt.ticks = atoi (ticks_label.get_text());
1842 nframes_t ret = session->convert_to_frames_at (pos, any);
1849 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1852 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1859 bbt.bars = atoi (bars_label.get_text());
1860 bbt.beats = atoi (beats_label.get_text());
1861 bbt.ticks = atoi (ticks_label.get_text());
1863 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1867 AudioClock::audio_frame_from_display () const
1869 return (nframes_t) atoi (audio_frames_label.get_text());
1873 AudioClock::build_ops_menu ()
1875 using namespace Menu_Helpers;
1876 ops_menu = new Menu;
1877 MenuList& ops_items = ops_menu->items();
1878 ops_menu->set_name ("ArdourContextMenu");
1880 ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1881 ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1882 ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1883 ops_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1884 ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1888 AudioClock::set_mode (Mode m)
1890 /* slightly tricky: this is called from within the ARDOUR_UI
1891 constructor by some of its clock members. at that time
1892 the instance pointer is unset, so we have to be careful.
1893 the main idea is to drop keyboard focus in case we had
1894 started editing the clock and then we switch clock mode.
1897 clock_base.grab_focus ();
1903 clock_base.remove ();
1909 clock_base.add (smpte_packer_hbox);
1913 clock_base.add (bbt_packer_hbox);
1917 clock_base.add (minsec_packer_hbox);
1921 clock_base.add (frames_packer_hbox);
1925 clock_base.add (off_hbox);
1929 set_size_requests ();
1931 set (last_when, true);
1932 clock_base.show_all ();
1933 key_entry_state = 0;
1935 if (!is_transient) {
1936 ModeChanged (); /* EMIT SIGNAL */
1941 AudioClock::set_size_requests ()
1943 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
1947 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
1948 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
1949 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
1950 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
1954 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
1955 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
1956 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
1960 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
1961 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
1962 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
1966 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
1970 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);