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);
659 AudioClock::field_key_press_event (GdkEventKey *ev, Field field)
661 /* all key activity is handled on key release */
666 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
671 bool move_on = false;
675 label = &hours_label;
678 label = &minutes_label;
681 label = &seconds_label;
684 label = &frames_label;
688 label = &audio_frames_label;
692 label = &ms_hours_label;
695 label = &ms_minutes_label;
698 label = &ms_seconds_label;
705 label = &beats_label;
708 label = &ticks_label;
714 switch (ev->keyval) {
758 if (_mode == MinSec && field == MS_Seconds) {
772 clock_base.grab_focus ();
781 if (key_entry_state == 0) {
783 /* initialize with a fresh new string */
785 if (field != AudioFrames) {
786 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
795 string existing = label->get_text();
796 if (existing.length() >= field_length[field]) {
797 new_text = existing.substr (1, field_length[field] - 1);
799 new_text = existing.substr (0, field_length[field] - 1);
803 new_text += new_char;
804 label->set_text (new_text);
808 if (key_entry_state == field_length[field]) {
814 if (key_entry_state) {
821 // Check SMPTE fields for sanity (may also adjust fields)
822 smpte_sanitize_display();
827 // Bars or beats should never be 0
828 if (atoi(bars_label.get_text()) == 0) {
829 bars_label.set_text("001");
831 if (atoi(beats_label.get_text()) == 0) {
832 beats_label.set_text("01");
839 ValueChanged(); /* EMIT_SIGNAL */
842 /* move on to the next field.
850 minutes_ebox.grab_focus ();
853 seconds_ebox.grab_focus ();
856 frames_ebox.grab_focus ();
859 clock_base.grab_focus ();
864 clock_base.grab_focus ();
870 ms_minutes_ebox.grab_focus ();
873 ms_seconds_ebox.grab_focus ();
876 clock_base.grab_focus ();
882 beats_ebox.grab_focus ();
885 ticks_ebox.grab_focus ();
888 clock_base.grab_focus ();
901 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
905 Keyboard::magic_widget_grab_focus ();
909 hours_ebox.set_flags (Gtk::HAS_FOCUS);
910 hours_ebox.set_state (Gtk::STATE_ACTIVE);
913 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
914 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
917 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
918 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
921 frames_ebox.set_flags (Gtk::HAS_FOCUS);
922 frames_ebox.set_state (Gtk::STATE_ACTIVE);
926 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
927 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
931 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
932 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
935 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
936 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
939 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
940 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
943 bars_ebox.set_flags (Gtk::HAS_FOCUS);
944 bars_ebox.set_state (Gtk::STATE_ACTIVE);
947 beats_ebox.set_flags (Gtk::HAS_FOCUS);
948 beats_ebox.set_state (Gtk::STATE_ACTIVE);
951 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
952 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
960 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
965 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
966 hours_ebox.set_state (Gtk::STATE_NORMAL);
969 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
970 minutes_ebox.set_state (Gtk::STATE_NORMAL);
973 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
974 seconds_ebox.set_state (Gtk::STATE_NORMAL);
977 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
978 frames_ebox.set_state (Gtk::STATE_NORMAL);
982 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
983 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
987 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
988 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
991 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
992 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
995 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
996 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1000 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1001 bars_ebox.set_state (Gtk::STATE_NORMAL);
1004 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1005 beats_ebox.set_state (Gtk::STATE_NORMAL);
1008 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1009 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1013 Keyboard::magic_widget_drop_focus ();
1019 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1022 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1024 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
1025 // we actually dragged so return without setting editing focus, or we shift clicked
1031 if (ops_menu == 0) {
1034 ops_menu->popup (1, ev->time);
1038 if (Keyboard::is_context_menu_event (ev)) {
1039 if (ops_menu == 0) {
1042 ops_menu->popup (1, ev->time);
1046 switch (ev->button) {
1050 hours_ebox.grab_focus();
1053 minutes_ebox.grab_focus();
1056 seconds_ebox.grab_focus();
1059 frames_ebox.grab_focus();
1063 audio_frames_ebox.grab_focus();
1067 ms_hours_ebox.grab_focus();
1070 ms_minutes_ebox.grab_focus();
1073 ms_seconds_ebox.grab_focus();
1077 bars_ebox.grab_focus ();
1080 beats_ebox.grab_focus ();
1083 ticks_ebox.grab_focus ();
1096 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
1098 if (session == 0) return false;
1100 nframes_t frames = 0;
1102 switch (ev->button) {
1104 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1106 ValueChanged (); /* EMIT_SIGNAL */
1109 /* make absolutely sure that the pointer is grabbed */
1110 gdk_pointer_grab(ev->window,false ,
1111 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1112 NULL,NULL,ev->time);
1115 drag_start_y = ev->y;
1120 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1122 ValueChanged (); /* EMIT_SIGNAL */
1127 /* used for context sensitive menu */
1140 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1146 nframes_t frames = 0;
1148 switch (ev->direction) {
1151 frames = get_frames (field);
1153 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1156 set (current_time() + frames, true);
1157 ValueChanged (); /* EMIT_SIGNAL */
1161 case GDK_SCROLL_DOWN:
1162 frames = get_frames (field);
1164 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1168 if ((double)current_time() - (double)frames < 0.0) {
1171 set (current_time() - frames, true);
1174 ValueChanged (); /* EMIT_SIGNAL */
1187 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1189 if (session == 0 || !dragging) {
1193 float pixel_frame_scale_factor = 0.2f;
1196 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1197 pixel_frame_scale_factor = 0.1f;
1201 if (Keyboard::modifier_state_contains (ev->state,
1202 Keyboard::Control|Keyboard::Alt)) {
1204 pixel_frame_scale_factor = 0.025f;
1207 double y_delta = ev->y - drag_y;
1209 drag_accum += y_delta*pixel_frame_scale_factor;
1213 if (trunc(drag_accum) != 0) {
1218 dir = (drag_accum < 0 ? 1:-1);
1219 pos = current_time();
1220 frames = get_frames (field,pos,dir);
1222 if (frames != 0 && frames * drag_accum < current_time()) {
1224 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1232 ValueChanged(); /* EMIT_SIGNAL */
1241 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1244 nframes_t frames = 0;
1248 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1251 frames = (nframes_t) floor (60.0 * session->frame_rate());
1254 frames = session->frame_rate();
1257 frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second());
1265 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1268 frames = (nframes_t) floor (60.0 * session->frame_rate());
1271 frames = session->frame_rate();
1278 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1284 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1290 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1298 AudioClock::current_time (nframes_t pos) const
1304 ret = smpte_frame_from_display ();
1307 ret = bbt_frame_from_display (pos);
1311 ret = minsec_frame_from_display ();
1315 ret = audio_frame_from_display ();
1326 AudioClock::current_duration (nframes_t pos) const
1332 ret = smpte_frame_from_display ();
1335 ret = bbt_frame_duration_from_display (pos);
1339 ret = minsec_frame_from_display ();
1343 ret = audio_frame_from_display ();
1354 AudioClock::smpte_sanitize_display()
1356 // Check SMPTE fields for sanity, possibly adjusting values
1357 if (atoi(minutes_label.get_text()) > 59) {
1358 minutes_label.set_text("59");
1361 if (atoi(seconds_label.get_text()) > 59) {
1362 seconds_label.set_text("59");
1365 switch ((long)rint(session->smpte_frames_per_second())) {
1367 if (atoi(frames_label.get_text()) > 23) {
1368 frames_label.set_text("23");
1372 if (atoi(frames_label.get_text()) > 24) {
1373 frames_label.set_text("24");
1377 if (atoi(frames_label.get_text()) > 29) {
1378 frames_label.set_text("29");
1385 if (session->smpte_drop_frames()) {
1386 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1387 frames_label.set_text("02");
1393 AudioClock::smpte_frame_from_display () const
1402 smpte.hours = atoi (hours_label.get_text());
1403 smpte.minutes = atoi (minutes_label.get_text());
1404 smpte.seconds = atoi (seconds_label.get_text());
1405 smpte.frames = atoi (frames_label.get_text());
1406 smpte.rate = session->smpte_frames_per_second();
1407 smpte.drop= session->smpte_drop_frames();
1409 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1413 #define SMPTE_SAMPLE_TEST_1
1414 #define SMPTE_SAMPLE_TEST_2
1415 #define SMPTE_SAMPLE_TEST_3
1416 #define SMPTE_SAMPLE_TEST_4
1417 #define SMPTE_SAMPLE_TEST_5
1418 #define SMPTE_SAMPLE_TEST_6
1419 #define SMPTE_SAMPLE_TEST_7
1421 // Testcode for smpte<->sample conversions (P.S.)
1424 nframes_t oldsample = 0;
1426 nframes_t sample_increment;
1428 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1430 #ifdef SMPTE_SAMPLE_TEST_1
1431 // Test 1: use_offset = false, use_subframes = false
1432 cout << "use_offset = false, use_subframes = false" << endl;
1433 for (int i = 0; i < 108003; i++) {
1434 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1435 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1437 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1438 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1439 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1440 cout << "sample: " << sample1 << endl;
1441 cout << "sample: " << sample1 << " -> ";
1442 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1446 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1447 cout << "ERROR: smpte2 not equal smpte1" << endl;
1448 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1449 cout << "sample: " << sample1 << endl;
1450 cout << "sample: " << sample1 << " -> ";
1451 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1454 oldsample = sample1;
1455 session->smpte_increment( smpte1 );
1458 cout << "sample_increment: " << sample_increment << endl;
1459 cout << "sample: " << sample1 << " -> ";
1460 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1463 #ifdef SMPTE_SAMPLE_TEST_2
1464 // Test 2: use_offset = true, use_subframes = false
1465 cout << "use_offset = true, use_subframes = false" << endl;
1471 smpte1.subframes = 0;
1472 sample1 = oldsample = 0;
1474 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1475 cout << "Starting at sample: " << sample1 << " -> ";
1476 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1478 for (int i = 0; i < 108003; i++) {
1479 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1480 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1482 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1483 // cout << "sample: " << sample1 << endl;
1484 // cout << "sample: " << sample1 << " -> ";
1485 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1487 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1488 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1489 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1490 cout << "sample: " << sample1 << endl;
1491 cout << "sample: " << sample1 << " -> ";
1492 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1496 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1497 cout << "ERROR: smpte2 not equal smpte1" << endl;
1498 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1499 cout << "sample: " << sample1 << endl;
1500 cout << "sample: " << sample1 << " -> ";
1501 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1504 oldsample = sample1;
1505 session->smpte_increment( smpte1 );
1508 cout << "sample_increment: " << sample_increment << endl;
1509 cout << "sample: " << sample1 << " -> ";
1510 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1513 #ifdef SMPTE_SAMPLE_TEST_3
1514 // Test 3: use_offset = true, use_subframes = false, decrement
1515 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1517 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1518 cout << "Starting at sample: " << sample1 << " -> ";
1519 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1521 for (int i = 0; i < 108003; i++) {
1522 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1523 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1525 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1526 // cout << "sample: " << sample1 << endl;
1527 // cout << "sample: " << sample1 << " -> ";
1528 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1530 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1531 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1532 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1533 cout << "sample: " << sample1 << endl;
1534 cout << "sample: " << sample1 << " -> ";
1535 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1539 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1540 cout << "ERROR: smpte2 not equal smpte1" << endl;
1541 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1542 cout << "sample: " << sample1 << endl;
1543 cout << "sample: " << sample1 << " -> ";
1544 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1547 oldsample = sample1;
1548 session->smpte_decrement( smpte1 );
1551 cout << "sample_decrement: " << sample_increment << endl;
1552 cout << "sample: " << sample1 << " -> ";
1553 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1557 #ifdef SMPTE_SAMPLE_TEST_4
1558 // Test 4: use_offset = true, use_subframes = true
1559 cout << "use_offset = true, use_subframes = true" << endl;
1561 for (long sub = 5; sub < 80; sub += 5) {
1566 smpte1.subframes = 0;
1567 sample1 = oldsample = (sample_increment * sub) / 80;
1569 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1571 cout << "starting at sample: " << sample1 << " -> ";
1572 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1574 for (int i = 0; i < 108003; i++) {
1575 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1576 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1578 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1579 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1580 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1581 cout << "sample: " << sample1 << endl;
1582 cout << "sample: " << sample1 << " -> ";
1583 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1587 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1588 cout << "ERROR: smpte2 not equal smpte1" << endl;
1589 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1590 cout << "sample: " << sample1 << endl;
1591 cout << "sample: " << sample1 << " -> ";
1592 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1595 oldsample = sample1;
1596 session->smpte_increment( smpte1 );
1599 cout << "sample_increment: " << sample_increment << endl;
1600 cout << "sample: " << sample1 << " -> ";
1601 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1603 for (int i = 0; i < 108003; i++) {
1604 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1605 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1607 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1608 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1609 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1610 cout << "sample: " << sample1 << endl;
1611 cout << "sample: " << sample1 << " -> ";
1612 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1616 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1617 cout << "ERROR: smpte2 not equal smpte1" << endl;
1618 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1619 cout << "sample: " << sample1 << endl;
1620 cout << "sample: " << sample1 << " -> ";
1621 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1624 oldsample = sample1;
1625 session->smpte_decrement( smpte1 );
1628 cout << "sample_decrement: " << sample_increment << endl;
1629 cout << "sample: " << sample1 << " -> ";
1630 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1635 #ifdef SMPTE_SAMPLE_TEST_5
1636 // Test 5: use_offset = true, use_subframes = false, increment seconds
1637 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1643 smpte1.subframes = 0;
1644 sample1 = oldsample = 0;
1645 sample_increment = session->frame_rate();
1647 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1648 cout << "Starting at sample: " << sample1 << " -> ";
1649 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1651 for (int i = 0; i < 3600; i++) {
1652 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1653 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1655 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1656 // cout << "sample: " << sample1 << endl;
1657 // cout << "sample: " << sample1 << " -> ";
1658 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1660 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1662 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1666 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1667 cout << "ERROR: smpte2 not equal smpte1" << endl;
1668 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1669 cout << "sample: " << sample1 << endl;
1670 cout << "sample: " << sample1 << " -> ";
1671 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1674 oldsample = sample1;
1675 session->smpte_increment_seconds( smpte1 );
1678 cout << "sample_increment: " << sample_increment << endl;
1679 cout << "sample: " << sample1 << " -> ";
1680 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1684 #ifdef SMPTE_SAMPLE_TEST_6
1685 // Test 6: use_offset = true, use_subframes = false, increment minutes
1686 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1692 smpte1.subframes = 0;
1693 sample1 = oldsample = 0;
1694 sample_increment = session->frame_rate() * 60;
1696 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1697 cout << "Starting at sample: " << sample1 << " -> ";
1698 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1700 for (int i = 0; i < 60; i++) {
1701 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1702 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1704 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1705 // cout << "sample: " << sample1 << endl;
1706 // cout << "sample: " << sample1 << " -> ";
1707 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1709 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1711 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1715 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1716 cout << "ERROR: smpte2 not equal smpte1" << endl;
1717 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1718 cout << "sample: " << sample1 << endl;
1719 cout << "sample: " << sample1 << " -> ";
1720 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1723 oldsample = sample1;
1724 session->smpte_increment_minutes( smpte1 );
1727 cout << "sample_increment: " << sample_increment << endl;
1728 cout << "sample: " << sample1 << " -> ";
1729 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1732 #ifdef SMPTE_SAMPLE_TEST_7
1733 // Test 7: use_offset = true, use_subframes = false, increment hours
1734 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1740 smpte1.subframes = 0;
1741 sample1 = oldsample = 0;
1742 sample_increment = session->frame_rate() * 60 * 60;
1744 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1745 cout << "Starting at sample: " << sample1 << " -> ";
1746 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1748 for (int i = 0; i < 10; i++) {
1749 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1750 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1752 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1753 // cout << "sample: " << sample1 << endl;
1754 // cout << "sample: " << sample1 << " -> ";
1755 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1757 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1759 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1763 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1764 cout << "ERROR: smpte2 not equal smpte1" << endl;
1765 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1766 cout << "sample: " << sample1 << endl;
1767 cout << "sample: " << sample1 << " -> ";
1768 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1771 oldsample = sample1;
1772 session->smpte_increment_hours( smpte1 );
1775 cout << "sample_increment: " << sample_increment << endl;
1776 cout << "sample: " << sample1 << " -> ";
1777 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1786 AudioClock::minsec_frame_from_display () const
1792 int hrs = atoi (ms_hours_label.get_text());
1793 int mins = atoi (ms_minutes_label.get_text());
1794 float secs = atof (ms_seconds_label.get_text());
1796 nframes_t sr = session->frame_rate();
1798 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1802 AudioClock::bbt_frame_from_display (nframes_t pos) const
1805 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1810 any.type = AnyTime::BBT;
1812 any.bbt.bars = atoi (bars_label.get_text());
1813 any.bbt.beats = atoi (beats_label.get_text());
1814 any.bbt.ticks = atoi (ticks_label.get_text());
1816 nframes_t ret = session->convert_to_frames_at (pos, any);
1823 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1826 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1833 bbt.bars = atoi (bars_label.get_text());
1834 bbt.beats = atoi (beats_label.get_text());
1835 bbt.ticks = atoi (ticks_label.get_text());
1837 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1841 AudioClock::audio_frame_from_display () const
1843 return (nframes_t) atoi (audio_frames_label.get_text());
1847 AudioClock::build_ops_menu ()
1849 using namespace Menu_Helpers;
1850 ops_menu = new Menu;
1851 MenuList& ops_items = ops_menu->items();
1852 ops_menu->set_name ("ArdourContextMenu");
1854 ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1855 ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1856 ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1857 ops_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1858 ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1862 AudioClock::set_mode (Mode m)
1864 /* slightly tricky: this is called from within the ARDOUR_UI
1865 constructor by some of its clock members. at that time
1866 the instance pointer is unset, so we have to be careful.
1867 the main idea is to drop keyboard focus in case we had
1868 started editing the clock and then we switch clock mode.
1871 clock_base.grab_focus ();
1877 clock_base.remove ();
1883 clock_base.add (smpte_packer_hbox);
1887 clock_base.add (bbt_packer_hbox);
1891 clock_base.add (minsec_packer_hbox);
1895 clock_base.add (frames_packer_hbox);
1899 clock_base.add (off_hbox);
1903 set_size_requests ();
1905 set (last_when, true);
1906 clock_base.show_all ();
1907 key_entry_state = 0;
1909 if (!is_transient) {
1910 ModeChanged (); /* EMIT SIGNAL */
1915 AudioClock::set_size_requests ()
1917 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
1921 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
1922 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
1923 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
1924 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
1928 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
1929 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
1930 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
1934 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
1935 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
1936 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
1940 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
1944 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);