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 ((fabs(smpte_frames - 29.97) < 0.0001) || smpte_frames == 30) {
604 if (session->smpte_drop_frames()) {
607 sprintf (buf, "NDF");
610 // there is no drop frame alternative
614 smpte_lower_info_label->set_text (buf);
619 AudioClock::set_bbt (nframes_t when, bool force)
624 session->tempo_map().bbt_time (when, bbt);
625 sprintf (buf, "%03" PRIu32, bbt.bars);
626 bars_label.set_text (buf);
627 sprintf (buf, "%02" PRIu32, bbt.beats);
628 beats_label.set_text (buf);
629 sprintf (buf, "%04" PRIu32, bbt.ticks);
630 ticks_label.set_text (buf);
632 if (bbt_upper_info_label) {
633 TempoMap::Metric m (session->tempo_map().metric_at (when));
634 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
635 bbt_lower_info_label->set_text (buf);
636 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
637 bbt_upper_info_label->set_text (buf);
642 AudioClock::set_session (Session *s)
649 XMLNode* node = session->extra_xml (X_("ClockModes"));
650 AudioClock::Mode amode;
653 if ((prop = node->property (_name)) != 0) {
654 amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
659 set (last_when, true);
668 hours_ebox.grab_focus ();
672 bars_ebox.grab_focus ();
676 ms_hours_ebox.grab_focus ();
680 frames_ebox.grab_focus ();
690 AudioClock::field_key_press_event (GdkEventKey *ev, Field field)
692 /* all key activity is handled on key release */
697 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
702 bool move_on = false;
706 label = &hours_label;
709 label = &minutes_label;
712 label = &seconds_label;
715 label = &frames_label;
719 label = &audio_frames_label;
723 label = &ms_hours_label;
726 label = &ms_minutes_label;
729 label = &ms_seconds_label;
736 label = &beats_label;
739 label = &ticks_label;
745 switch (ev->keyval) {
789 if (_mode == MinSec && field == MS_Seconds) {
803 clock_base.grab_focus ();
812 if (key_entry_state == 0) {
814 /* initialize with a fresh new string */
816 if (field != AudioFrames) {
817 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
826 string existing = label->get_text();
827 if (existing.length() >= field_length[field]) {
828 new_text = existing.substr (1, field_length[field] - 1);
830 new_text = existing.substr (0, field_length[field] - 1);
834 new_text += new_char;
835 label->set_text (new_text);
839 if (key_entry_state == field_length[field]) {
845 if (key_entry_state) {
852 // Check SMPTE fields for sanity (may also adjust fields)
853 smpte_sanitize_display();
858 // Bars or beats should never be 0
859 if (atoi(bars_label.get_text()) == 0) {
860 bars_label.set_text("001");
862 if (atoi(beats_label.get_text()) == 0) {
863 beats_label.set_text("01");
870 ValueChanged(); /* EMIT_SIGNAL */
873 /* move on to the next field.
881 minutes_ebox.grab_focus ();
884 seconds_ebox.grab_focus ();
887 frames_ebox.grab_focus ();
890 clock_base.grab_focus ();
895 clock_base.grab_focus ();
901 ms_minutes_ebox.grab_focus ();
904 ms_seconds_ebox.grab_focus ();
907 clock_base.grab_focus ();
913 beats_ebox.grab_focus ();
916 ticks_ebox.grab_focus ();
919 clock_base.grab_focus ();
932 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
936 Keyboard::magic_widget_grab_focus ();
940 hours_ebox.set_flags (Gtk::HAS_FOCUS);
941 hours_ebox.set_state (Gtk::STATE_ACTIVE);
944 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
945 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
948 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
949 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
952 frames_ebox.set_flags (Gtk::HAS_FOCUS);
953 frames_ebox.set_state (Gtk::STATE_ACTIVE);
957 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
958 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
962 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
963 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
966 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
967 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
970 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
971 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
974 bars_ebox.set_flags (Gtk::HAS_FOCUS);
975 bars_ebox.set_state (Gtk::STATE_ACTIVE);
978 beats_ebox.set_flags (Gtk::HAS_FOCUS);
979 beats_ebox.set_state (Gtk::STATE_ACTIVE);
982 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
983 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
991 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
996 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
997 hours_ebox.set_state (Gtk::STATE_NORMAL);
1000 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1001 minutes_ebox.set_state (Gtk::STATE_NORMAL);
1004 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1005 seconds_ebox.set_state (Gtk::STATE_NORMAL);
1008 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1009 frames_ebox.set_state (Gtk::STATE_NORMAL);
1013 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1014 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
1018 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1019 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
1022 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1023 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
1026 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1027 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1031 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1032 bars_ebox.set_state (Gtk::STATE_NORMAL);
1035 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1036 beats_ebox.set_state (Gtk::STATE_NORMAL);
1039 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1040 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1044 Keyboard::magic_widget_drop_focus ();
1050 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1053 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1055 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
1056 // we actually dragged so return without setting editing focus, or we shift clicked
1062 if (ops_menu == 0) {
1065 ops_menu->popup (1, ev->time);
1069 if (Keyboard::is_context_menu_event (ev)) {
1070 if (ops_menu == 0) {
1073 ops_menu->popup (1, ev->time);
1077 switch (ev->button) {
1081 hours_ebox.grab_focus();
1084 minutes_ebox.grab_focus();
1087 seconds_ebox.grab_focus();
1090 frames_ebox.grab_focus();
1094 audio_frames_ebox.grab_focus();
1098 ms_hours_ebox.grab_focus();
1101 ms_minutes_ebox.grab_focus();
1104 ms_seconds_ebox.grab_focus();
1108 bars_ebox.grab_focus ();
1111 beats_ebox.grab_focus ();
1114 ticks_ebox.grab_focus ();
1127 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
1129 if (session == 0) return false;
1131 nframes_t frames = 0;
1133 switch (ev->button) {
1135 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1137 ValueChanged (); /* EMIT_SIGNAL */
1140 /* make absolutely sure that the pointer is grabbed */
1141 gdk_pointer_grab(ev->window,false ,
1142 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1143 NULL,NULL,ev->time);
1146 drag_start_y = ev->y;
1151 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1153 ValueChanged (); /* EMIT_SIGNAL */
1158 /* used for context sensitive menu */
1171 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1177 nframes_t frames = 0;
1179 switch (ev->direction) {
1182 frames = get_frames (field);
1184 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1187 set (current_time() + frames, true);
1188 ValueChanged (); /* EMIT_SIGNAL */
1192 case GDK_SCROLL_DOWN:
1193 frames = get_frames (field);
1195 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1199 if ((double)current_time() - (double)frames < 0.0) {
1202 set (current_time() - frames, true);
1205 ValueChanged (); /* EMIT_SIGNAL */
1218 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1220 if (session == 0 || !dragging) {
1224 float pixel_frame_scale_factor = 0.2f;
1227 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1228 pixel_frame_scale_factor = 0.1f;
1232 if (Keyboard::modifier_state_contains (ev->state,
1233 Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) {
1235 pixel_frame_scale_factor = 0.025f;
1238 double y_delta = ev->y - drag_y;
1240 drag_accum += y_delta*pixel_frame_scale_factor;
1244 if (trunc(drag_accum) != 0) {
1249 dir = (drag_accum < 0 ? 1:-1);
1250 pos = current_time();
1251 frames = get_frames (field,pos,dir);
1253 if (frames != 0 && frames * drag_accum < current_time()) {
1255 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1263 ValueChanged(); /* EMIT_SIGNAL */
1272 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1275 nframes_t frames = 0;
1279 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1282 frames = (nframes_t) floor (60.0 * session->frame_rate());
1285 frames = session->frame_rate();
1288 frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second());
1296 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1299 frames = (nframes_t) floor (60.0 * session->frame_rate());
1302 frames = session->frame_rate();
1309 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1315 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1321 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1329 AudioClock::current_time (nframes_t pos) const
1335 ret = smpte_frame_from_display ();
1338 ret = bbt_frame_from_display (pos);
1342 ret = minsec_frame_from_display ();
1346 ret = audio_frame_from_display ();
1357 AudioClock::current_duration (nframes_t pos) const
1363 ret = smpte_frame_from_display ();
1366 ret = bbt_frame_duration_from_display (pos);
1370 ret = minsec_frame_from_display ();
1374 ret = audio_frame_from_display ();
1385 AudioClock::smpte_sanitize_display()
1387 // Check SMPTE fields for sanity, possibly adjusting values
1388 if (atoi(minutes_label.get_text()) > 59) {
1389 minutes_label.set_text("59");
1392 if (atoi(seconds_label.get_text()) > 59) {
1393 seconds_label.set_text("59");
1396 switch ((long)rint(session->smpte_frames_per_second())) {
1398 if (atoi(frames_label.get_text()) > 23) {
1399 frames_label.set_text("23");
1403 if (atoi(frames_label.get_text()) > 24) {
1404 frames_label.set_text("24");
1408 if (atoi(frames_label.get_text()) > 29) {
1409 frames_label.set_text("29");
1416 if (session->smpte_drop_frames()) {
1417 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1418 frames_label.set_text("02");
1424 AudioClock::smpte_frame_from_display () const
1433 smpte.hours = atoi (hours_label.get_text());
1434 smpte.minutes = atoi (minutes_label.get_text());
1435 smpte.seconds = atoi (seconds_label.get_text());
1436 smpte.frames = atoi (frames_label.get_text());
1437 smpte.rate = session->smpte_frames_per_second();
1438 smpte.drop= session->smpte_drop_frames();
1440 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1444 #define SMPTE_SAMPLE_TEST_1
1445 #define SMPTE_SAMPLE_TEST_2
1446 #define SMPTE_SAMPLE_TEST_3
1447 #define SMPTE_SAMPLE_TEST_4
1448 #define SMPTE_SAMPLE_TEST_5
1449 #define SMPTE_SAMPLE_TEST_6
1450 #define SMPTE_SAMPLE_TEST_7
1452 // Testcode for smpte<->sample conversions (P.S.)
1455 nframes_t oldsample = 0;
1457 nframes_t sample_increment;
1459 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1461 #ifdef SMPTE_SAMPLE_TEST_1
1462 // Test 1: use_offset = false, use_subframes = false
1463 cout << "use_offset = false, use_subframes = false" << endl;
1464 for (int i = 0; i < 108003; i++) {
1465 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1466 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1468 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1469 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1470 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1471 cout << "sample: " << sample1 << endl;
1472 cout << "sample: " << sample1 << " -> ";
1473 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1477 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1478 cout << "ERROR: smpte2 not equal smpte1" << endl;
1479 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1480 cout << "sample: " << sample1 << endl;
1481 cout << "sample: " << sample1 << " -> ";
1482 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1485 oldsample = sample1;
1486 session->smpte_increment( smpte1 );
1489 cout << "sample_increment: " << sample_increment << endl;
1490 cout << "sample: " << sample1 << " -> ";
1491 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1494 #ifdef SMPTE_SAMPLE_TEST_2
1495 // Test 2: use_offset = true, use_subframes = false
1496 cout << "use_offset = true, use_subframes = false" << endl;
1502 smpte1.subframes = 0;
1503 sample1 = oldsample = 0;
1505 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1506 cout << "Starting at sample: " << sample1 << " -> ";
1507 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1509 for (int i = 0; i < 108003; i++) {
1510 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1511 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1513 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1514 // cout << "sample: " << sample1 << endl;
1515 // cout << "sample: " << sample1 << " -> ";
1516 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1518 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1519 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1520 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1521 cout << "sample: " << sample1 << endl;
1522 cout << "sample: " << sample1 << " -> ";
1523 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1527 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1528 cout << "ERROR: smpte2 not equal smpte1" << endl;
1529 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1530 cout << "sample: " << sample1 << endl;
1531 cout << "sample: " << sample1 << " -> ";
1532 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1535 oldsample = sample1;
1536 session->smpte_increment( smpte1 );
1539 cout << "sample_increment: " << sample_increment << endl;
1540 cout << "sample: " << sample1 << " -> ";
1541 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1544 #ifdef SMPTE_SAMPLE_TEST_3
1545 // Test 3: use_offset = true, use_subframes = false, decrement
1546 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1548 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1549 cout << "Starting at sample: " << sample1 << " -> ";
1550 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1552 for (int i = 0; i < 108003; i++) {
1553 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1554 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1556 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1557 // cout << "sample: " << sample1 << endl;
1558 // cout << "sample: " << sample1 << " -> ";
1559 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1561 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1562 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1563 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1564 cout << "sample: " << sample1 << endl;
1565 cout << "sample: " << sample1 << " -> ";
1566 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1570 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1571 cout << "ERROR: smpte2 not equal smpte1" << endl;
1572 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1573 cout << "sample: " << sample1 << endl;
1574 cout << "sample: " << sample1 << " -> ";
1575 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1578 oldsample = sample1;
1579 session->smpte_decrement( smpte1 );
1582 cout << "sample_decrement: " << sample_increment << endl;
1583 cout << "sample: " << sample1 << " -> ";
1584 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1588 #ifdef SMPTE_SAMPLE_TEST_4
1589 // Test 4: use_offset = true, use_subframes = true
1590 cout << "use_offset = true, use_subframes = true" << endl;
1592 for (long sub = 5; sub < 80; sub += 5) {
1597 smpte1.subframes = 0;
1598 sample1 = oldsample = (sample_increment * sub) / 80;
1600 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1602 cout << "starting at sample: " << sample1 << " -> ";
1603 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1605 for (int i = 0; i < 108003; i++) {
1606 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1607 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1609 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1610 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1611 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1612 cout << "sample: " << sample1 << endl;
1613 cout << "sample: " << sample1 << " -> ";
1614 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1618 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1619 cout << "ERROR: smpte2 not equal smpte1" << endl;
1620 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1621 cout << "sample: " << sample1 << endl;
1622 cout << "sample: " << sample1 << " -> ";
1623 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1626 oldsample = sample1;
1627 session->smpte_increment( smpte1 );
1630 cout << "sample_increment: " << sample_increment << endl;
1631 cout << "sample: " << sample1 << " -> ";
1632 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1634 for (int i = 0; i < 108003; i++) {
1635 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1636 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1638 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1639 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1640 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1641 cout << "sample: " << sample1 << endl;
1642 cout << "sample: " << sample1 << " -> ";
1643 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1647 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1648 cout << "ERROR: smpte2 not equal smpte1" << endl;
1649 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1650 cout << "sample: " << sample1 << endl;
1651 cout << "sample: " << sample1 << " -> ";
1652 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1655 oldsample = sample1;
1656 session->smpte_decrement( smpte1 );
1659 cout << "sample_decrement: " << sample_increment << endl;
1660 cout << "sample: " << sample1 << " -> ";
1661 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1666 #ifdef SMPTE_SAMPLE_TEST_5
1667 // Test 5: use_offset = true, use_subframes = false, increment seconds
1668 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1674 smpte1.subframes = 0;
1675 sample1 = oldsample = 0;
1676 sample_increment = session->frame_rate();
1678 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1679 cout << "Starting at sample: " << sample1 << " -> ";
1680 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1682 for (int i = 0; i < 3600; i++) {
1683 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1684 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1686 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1687 // cout << "sample: " << sample1 << endl;
1688 // cout << "sample: " << sample1 << " -> ";
1689 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1691 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1693 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1697 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1698 cout << "ERROR: smpte2 not equal smpte1" << endl;
1699 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1700 cout << "sample: " << sample1 << endl;
1701 cout << "sample: " << sample1 << " -> ";
1702 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1705 oldsample = sample1;
1706 session->smpte_increment_seconds( smpte1 );
1709 cout << "sample_increment: " << sample_increment << endl;
1710 cout << "sample: " << sample1 << " -> ";
1711 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1715 #ifdef SMPTE_SAMPLE_TEST_6
1716 // Test 6: use_offset = true, use_subframes = false, increment minutes
1717 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1723 smpte1.subframes = 0;
1724 sample1 = oldsample = 0;
1725 sample_increment = session->frame_rate() * 60;
1727 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1728 cout << "Starting at sample: " << sample1 << " -> ";
1729 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1731 for (int i = 0; i < 60; i++) {
1732 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1733 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1735 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1736 // cout << "sample: " << sample1 << endl;
1737 // cout << "sample: " << sample1 << " -> ";
1738 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1740 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1742 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1746 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1747 cout << "ERROR: smpte2 not equal smpte1" << endl;
1748 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1749 cout << "sample: " << sample1 << endl;
1750 cout << "sample: " << sample1 << " -> ";
1751 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1754 oldsample = sample1;
1755 session->smpte_increment_minutes( smpte1 );
1758 cout << "sample_increment: " << sample_increment << endl;
1759 cout << "sample: " << sample1 << " -> ";
1760 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1763 #ifdef SMPTE_SAMPLE_TEST_7
1764 // Test 7: use_offset = true, use_subframes = false, increment hours
1765 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1771 smpte1.subframes = 0;
1772 sample1 = oldsample = 0;
1773 sample_increment = session->frame_rate() * 60 * 60;
1775 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1776 cout << "Starting at sample: " << sample1 << " -> ";
1777 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1779 for (int i = 0; i < 10; i++) {
1780 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1781 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1783 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1784 // cout << "sample: " << sample1 << endl;
1785 // cout << "sample: " << sample1 << " -> ";
1786 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1788 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1790 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1794 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1795 cout << "ERROR: smpte2 not equal smpte1" << endl;
1796 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1797 cout << "sample: " << sample1 << endl;
1798 cout << "sample: " << sample1 << " -> ";
1799 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1802 oldsample = sample1;
1803 session->smpte_increment_hours( smpte1 );
1806 cout << "sample_increment: " << sample_increment << endl;
1807 cout << "sample: " << sample1 << " -> ";
1808 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1817 AudioClock::minsec_frame_from_display () const
1823 int hrs = atoi (ms_hours_label.get_text());
1824 int mins = atoi (ms_minutes_label.get_text());
1825 float secs = atof (ms_seconds_label.get_text());
1827 nframes_t sr = session->frame_rate();
1829 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1833 AudioClock::bbt_frame_from_display (nframes_t pos) const
1836 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1841 any.type = AnyTime::BBT;
1843 any.bbt.bars = atoi (bars_label.get_text());
1844 any.bbt.beats = atoi (beats_label.get_text());
1845 any.bbt.ticks = atoi (ticks_label.get_text());
1847 nframes_t ret = session->convert_to_frames_at (pos, any);
1854 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1857 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1864 bbt.bars = atoi (bars_label.get_text());
1865 bbt.beats = atoi (beats_label.get_text());
1866 bbt.ticks = atoi (ticks_label.get_text());
1868 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1872 AudioClock::audio_frame_from_display () const
1874 return (nframes_t) atoi (audio_frames_label.get_text());
1878 AudioClock::build_ops_menu ()
1880 using namespace Menu_Helpers;
1881 ops_menu = new Menu;
1882 MenuList& ops_items = ops_menu->items();
1883 ops_menu->set_name ("ArdourContextMenu");
1885 ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1886 ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1887 ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1888 ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1889 ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1893 AudioClock::set_mode (Mode m)
1895 /* slightly tricky: this is called from within the ARDOUR_UI
1896 constructor by some of its clock members. at that time
1897 the instance pointer is unset, so we have to be careful.
1898 the main idea is to drop keyboard focus in case we had
1899 started editing the clock and then we switch clock mode.
1902 clock_base.grab_focus ();
1908 clock_base.remove ();
1914 clock_base.add (smpte_packer_hbox);
1918 clock_base.add (bbt_packer_hbox);
1922 clock_base.add (minsec_packer_hbox);
1926 clock_base.add (frames_packer_hbox);
1930 clock_base.add (off_hbox);
1934 set_size_requests ();
1936 set (last_when, true);
1937 clock_base.show_all ();
1938 key_entry_state = 0;
1940 if (!is_transient) {
1941 ModeChanged (); /* EMIT SIGNAL */
1946 AudioClock::set_size_requests ()
1948 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
1952 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
1953 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
1954 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
1955 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
1959 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
1960 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
1961 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
1965 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
1966 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
1967 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
1971 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
1975 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);