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.
21 #include <cstdio> // for sprintf
24 #include <pbd/convert.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;
47 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
49 2, /* SMPTE_Minutes */
50 2, /* SMPTE_Seconds */
61 AudioClock::AudioClock (std::string name, bool allow_edit, bool duration, bool with_info)
62 : is_duration (duration),
63 editable (allow_edit),
79 frames_upper_info_label = manage (new Label);
80 frames_lower_info_label = manage (new Label);
81 smpte_upper_info_label = manage (new Label);
82 smpte_lower_info_label = manage (new Label);
83 bbt_upper_info_label = manage (new Label);
84 bbt_lower_info_label = manage (new Label);
86 frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
87 frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
88 smpte_upper_info_label->set_name ("AudioClockSMPTEUpperInfo");
89 smpte_lower_info_label->set_name ("AudioClockSMPTELowerInfo");
90 bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
91 bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
93 Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0);
94 Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0);
96 frames_info_box.pack_start (*frames_upper_info_label, true, true);
97 frames_info_box.pack_start (*frames_lower_info_label, true, true);
98 smpte_info_box.pack_start (*smpte_upper_info_label, true, true);
99 smpte_info_box.pack_start (*smpte_lower_info_label, true, true);
100 bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
101 bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
104 frames_upper_info_label = 0;
105 frames_lower_info_label = 0;
106 smpte_upper_info_label = 0;
107 smpte_lower_info_label = 0;
108 bbt_upper_info_label = 0;
109 bbt_lower_info_label = 0;
112 audio_frames_ebox.add (audio_frames_label);
114 frames_packer.set_homogeneous (false);
115 frames_packer.set_border_width (2);
116 frames_packer.pack_start (audio_frames_ebox, false, false);
119 frames_packer.pack_start (frames_info_box, false, false, 5);
122 frames_packer_hbox.pack_start (frames_packer, true, false);
124 hours_ebox.add (hours_label);
125 minutes_ebox.add (minutes_label);
126 seconds_ebox.add (seconds_label);
127 frames_ebox.add (frames_label);
128 bars_ebox.add (bars_label);
129 beats_ebox.add (beats_label);
130 ticks_ebox.add (ticks_label);
131 ms_hours_ebox.add (ms_hours_label);
132 ms_minutes_ebox.add (ms_minutes_label);
133 ms_seconds_ebox.add (ms_seconds_label);
135 smpte_packer.set_homogeneous (false);
136 smpte_packer.set_border_width (2);
137 smpte_packer.pack_start (hours_ebox, false, false);
138 smpte_packer.pack_start (colon1, false, false);
139 smpte_packer.pack_start (minutes_ebox, false, false);
140 smpte_packer.pack_start (colon2, false, false);
141 smpte_packer.pack_start (seconds_ebox, false, false);
142 smpte_packer.pack_start (colon3, false, false);
143 smpte_packer.pack_start (frames_ebox, false, false);
146 smpte_packer.pack_start (smpte_info_box, false, false, 5);
149 smpte_packer_hbox.pack_start (smpte_packer, true, false);
151 bbt_packer.set_homogeneous (false);
152 bbt_packer.set_border_width (2);
153 bbt_packer.pack_start (bars_ebox, false, false);
154 bbt_packer.pack_start (b1, false, false);
155 bbt_packer.pack_start (beats_ebox, false, false);
156 bbt_packer.pack_start (b2, false, false);
157 bbt_packer.pack_start (ticks_ebox, false, false);
160 bbt_packer.pack_start (bbt_info_box, false, false, 5);
163 bbt_packer_hbox.pack_start (bbt_packer, true, false);
165 minsec_packer.set_homogeneous (false);
166 minsec_packer.set_border_width (2);
167 minsec_packer.pack_start (ms_hours_ebox, false, false);
168 minsec_packer.pack_start (colon4, false, false);
169 minsec_packer.pack_start (ms_minutes_ebox, false, false);
170 minsec_packer.pack_start (colon5, false, false);
171 minsec_packer.pack_start (ms_seconds_ebox, false, false);
173 minsec_packer_hbox.pack_start (minsec_packer, true, false);
175 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
176 clock_frame.set_name ("BaseFrame");
178 clock_frame.add (clock_base);
182 _mode = BBT; /* lie to force mode switch */
185 pack_start (clock_frame, true, true);
187 /* the clock base handles button releases for menu popup regardless of
188 editable status. if the clock is editable, the clock base is where
189 we pass focus to after leaving the last editable "field", which
190 will then shutdown editing till the user starts it up again.
192 it does this because the focus out event on the field disables
193 keyboard event handling, and we don't connect anything up to
194 notice focus in on the clock base. hence, keyboard event handling
198 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
199 clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
201 Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
207 set (last_when, true);
211 AudioClock::set_name (string name)
213 Widget::set_name (name);
215 clock_base.set_name (name);
217 audio_frames_label.set_name (name);
218 hours_label.set_name (name);
219 minutes_label.set_name (name);
220 seconds_label.set_name (name);
221 frames_label.set_name (name);
222 bars_label.set_name (name);
223 beats_label.set_name (name);
224 ticks_label.set_name (name);
225 ms_hours_label.set_name (name);
226 ms_minutes_label.set_name (name);
227 ms_seconds_label.set_name (name);
228 hours_ebox.set_name (name);
229 minutes_ebox.set_name (name);
230 seconds_ebox.set_name (name);
231 frames_ebox.set_name (name);
232 audio_frames_ebox.set_name (name);
233 bars_ebox.set_name (name);
234 beats_ebox.set_name (name);
235 ticks_ebox.set_name (name);
236 ms_hours_ebox.set_name (name);
237 ms_minutes_ebox.set_name (name);
238 ms_seconds_ebox.set_name (name);
240 colon1.set_name (name);
241 colon2.set_name (name);
242 colon3.set_name (name);
243 colon4.set_name (name);
244 colon5.set_name (name);
252 AudioClock::setup_events ()
254 clock_base.set_flags (Gtk::CAN_FOCUS);
256 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);
257 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);
258 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);
259 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);
260 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);
261 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);
262 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);
263 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);
264 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);
265 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);
266 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);
268 hours_ebox.set_flags (Gtk::CAN_FOCUS);
269 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
270 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
271 frames_ebox.set_flags (Gtk::CAN_FOCUS);
272 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
273 bars_ebox.set_flags (Gtk::CAN_FOCUS);
274 beats_ebox.set_flags (Gtk::CAN_FOCUS);
275 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
276 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
277 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
278 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
280 hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
281 minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
282 seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
283 frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
284 audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
285 bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
286 beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
287 ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
288 ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
289 ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
290 ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
292 hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Hours));
293 minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
294 seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
295 frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Frames));
296 audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
297 bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
298 beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
299 ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
300 ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
301 ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
302 ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
304 hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Hours));
305 minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
306 seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
307 frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Frames));
308 audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
309 bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
310 beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
311 ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
312 ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
313 ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
314 ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
316 hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Hours));
317 minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Minutes));
318 seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Seconds));
319 frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), SMPTE_Frames));
320 audio_frames_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
321 bars_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
322 beats_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
323 ticks_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
324 ms_hours_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
325 ms_minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
326 ms_seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
328 hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours));
329 minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
330 seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
331 frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Frames));
332 audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
333 bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
334 beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
335 ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
336 ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
337 ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
338 ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
340 hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
341 minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
342 seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
343 frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
344 audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
345 bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
346 beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
347 ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
348 ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
349 ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
350 ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
352 hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
353 minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
354 seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
355 frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
356 audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
357 bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
358 beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
359 ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
360 ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
361 ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
362 ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
366 AudioClock::on_realize ()
370 /* styles are not available until the widgets are bound to a window */
372 set_size_requests ();
376 AudioClock::set (nframes_t when, bool force)
379 if ((!force && !is_visible()) || session == 0) {
383 if (when == last_when && !force) {
389 set_smpte (when, force);
393 set_bbt (when, force);
397 set_minsec (when, force);
401 set_frames (when, force);
412 AudioClock::smpte_offset_changed ()
419 current = current_duration();
421 current = current_time ();
431 AudioClock::set_frames (nframes_t when, bool force)
434 snprintf (buf, sizeof (buf), "%u", when);
435 audio_frames_label.set_text (buf);
437 if (frames_upper_info_label) {
438 nframes_t rate = session->frame_rate();
440 if (fmod (rate, 1000.0) == 0.000) {
441 sprintf (buf, "%uK", rate/1000);
443 sprintf (buf, "%.3fK", rate/1000.0f);
446 frames_upper_info_label->set_text (buf);
448 float vid_pullup = Config->get_video_pullup();
450 if (vid_pullup == 0.0) {
451 frames_lower_info_label->set_text(_("none"));
453 sprintf (buf, "%-6.4f", vid_pullup);
454 frames_lower_info_label->set_text (buf);
460 AudioClock::set_minsec (nframes_t when, bool force)
469 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
470 left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
471 mins = (int) floor (left / (session->frame_rate() * 60.0f));
472 left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
473 secs = left / (float) session->frame_rate();
475 if (force || hrs != ms_last_hrs) {
476 sprintf (buf, "%02d", hrs);
477 ms_hours_label.set_text (buf);
481 if (force || mins != ms_last_mins) {
482 sprintf (buf, "%02d", mins);
483 ms_minutes_label.set_text (buf);
487 if (force || secs != ms_last_secs) {
488 sprintf (buf, "%06.3f", secs);
489 ms_seconds_label.set_text (buf);
495 AudioClock::set_smpte (nframes_t when, bool force)
501 session->smpte_duration (when, smpte);
503 session->smpte_time (when, smpte);
506 if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
507 if (smpte.negative) {
508 sprintf (buf, "-%02" PRIu32, smpte.hours);
510 sprintf (buf, " %02" PRIu32, smpte.hours);
512 hours_label.set_text (buf);
513 last_hrs = smpte.hours;
514 last_negative = smpte.negative;
517 if (force || smpte.minutes != last_mins) {
518 sprintf (buf, "%02" PRIu32, smpte.minutes);
519 minutes_label.set_text (buf);
520 last_mins = smpte.minutes;
523 if (force || smpte.seconds != last_secs) {
524 sprintf (buf, "%02" PRIu32, smpte.seconds);
525 seconds_label.set_text (buf);
526 last_secs = smpte.seconds;
529 if (force || smpte.frames != last_frames) {
530 sprintf (buf, "%02" PRIu32, smpte.frames);
531 frames_label.set_text (buf);
532 last_frames = smpte.frames;
535 if (smpte_upper_info_label) {
536 float smpte_frames = session->smpte_frames_per_second();
538 if ( fmod(smpte_frames, 1.0) == 0.0) {
539 sprintf (buf, "%u", int (smpte_frames));
541 sprintf (buf, "%.2f", smpte_frames);
544 smpte_upper_info_label->set_text (buf);
546 if (session->smpte_drop_frames()) {
549 sprintf (buf, "NDF");
552 smpte_lower_info_label->set_text (buf);
557 AudioClock::set_bbt (nframes_t when, bool force)
562 session->tempo_map().bbt_time (when, bbt);
563 sprintf (buf, "%03" PRIu32, bbt.bars);
564 bars_label.set_text (buf);
565 sprintf (buf, "%02" PRIu32, bbt.beats);
566 beats_label.set_text (buf);
567 sprintf (buf, "%04" PRIu32, bbt.ticks);
568 ticks_label.set_text (buf);
570 if (bbt_upper_info_label) {
571 TempoMap::Metric m (session->tempo_map().metric_at (when));
572 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
573 bbt_lower_info_label->set_text (buf);
574 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
575 bbt_upper_info_label->set_text (buf);
580 AudioClock::set_session (Session *s)
585 set (last_when, true);
590 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
595 bool move_on = false;
599 label = &hours_label;
602 label = &minutes_label;
605 label = &seconds_label;
608 label = &frames_label;
612 label = &audio_frames_label;
616 label = &ms_hours_label;
619 label = &ms_minutes_label;
622 label = &ms_seconds_label;
629 label = &beats_label;
632 label = &ticks_label;
638 switch (ev->keyval) {
682 if (_mode == MinSec && field == MS_Seconds) {
696 clock_base.grab_focus ();
705 if (key_entry_state == 0) {
707 /* initialize with a fresh new string */
709 if (field != AudioFrames) {
710 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
719 string existing = label->get_text();
720 if (existing.length() >= field_length[field]) {
721 new_text = existing.substr (1, field_length[field] - 1);
723 new_text = existing.substr (0, field_length[field] - 1);
727 new_text += new_char;
728 label->set_text (new_text);
732 if (key_entry_state == field_length[field]) {
738 if (key_entry_state) {
745 // Check SMPTE fields for sanity (may also adjust fields)
746 smpte_sanitize_display();
752 ValueChanged(); /* EMIT_SIGNAL */
755 /* move on to the next field.
763 minutes_ebox.grab_focus ();
766 seconds_ebox.grab_focus ();
769 frames_ebox.grab_focus ();
772 clock_base.grab_focus ();
777 clock_base.grab_focus ();
783 ms_minutes_ebox.grab_focus ();
786 ms_seconds_ebox.grab_focus ();
789 clock_base.grab_focus ();
795 beats_ebox.grab_focus ();
798 ticks_ebox.grab_focus ();
801 clock_base.grab_focus ();
814 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
820 hours_ebox.set_flags (Gtk::HAS_FOCUS);
821 hours_ebox.set_state (Gtk::STATE_ACTIVE);
824 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
825 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
828 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
829 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
832 frames_ebox.set_flags (Gtk::HAS_FOCUS);
833 frames_ebox.set_state (Gtk::STATE_ACTIVE);
837 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
838 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
842 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
843 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
846 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
847 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
850 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
851 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
854 bars_ebox.set_flags (Gtk::HAS_FOCUS);
855 bars_ebox.set_state (Gtk::STATE_ACTIVE);
858 beats_ebox.set_flags (Gtk::HAS_FOCUS);
859 beats_ebox.set_state (Gtk::STATE_ACTIVE);
862 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
863 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
871 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
876 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
877 hours_ebox.set_state (Gtk::STATE_NORMAL);
880 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
881 minutes_ebox.set_state (Gtk::STATE_NORMAL);
884 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
885 seconds_ebox.set_state (Gtk::STATE_NORMAL);
888 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
889 frames_ebox.set_state (Gtk::STATE_NORMAL);
893 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
894 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
898 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
899 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
902 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
903 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
906 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
907 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
911 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
912 bars_ebox.set_state (Gtk::STATE_NORMAL);
915 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
916 beats_ebox.set_state (Gtk::STATE_NORMAL);
919 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
920 ticks_ebox.set_state (Gtk::STATE_NORMAL);
928 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
933 gdk_pointer_ungrab(GDK_CURRENT_TIME);
935 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
936 // we actually dragged so return without setting editing focus, or we shift clicked
946 ops_menu->popup (1, ev->time);
950 if (Keyboard::is_context_menu_event (ev)) {
954 ops_menu->popup (1, ev->time);
958 switch (ev->button) {
962 hours_ebox.grab_focus();
965 minutes_ebox.grab_focus();
968 seconds_ebox.grab_focus();
971 frames_ebox.grab_focus();
975 audio_frames_ebox.grab_focus();
979 ms_hours_ebox.grab_focus();
982 ms_minutes_ebox.grab_focus();
985 ms_seconds_ebox.grab_focus();
989 bars_ebox.grab_focus ();
992 beats_ebox.grab_focus ();
995 ticks_ebox.grab_focus ();
1008 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
1010 if (session == 0) return FALSE;
1012 nframes_t frames = 0;
1014 switch (ev->button) {
1016 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1018 ValueChanged (); /* EMIT_SIGNAL */
1021 /* make absolutely sure that the pointer is grabbed */
1022 gdk_pointer_grab(ev->window,FALSE ,
1023 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1024 NULL,NULL,ev->time);
1027 drag_start_y = ev->y;
1032 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1034 ValueChanged (); /* EMIT_SIGNAL */
1039 /* used for context sensitive menu */
1044 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1045 frames = get_frames (field);
1047 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1050 set (current_time() + frames, true);
1051 ValueChanged (); /* EMIT_SIGNAL */
1057 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
1058 frames = get_frames (field);
1060 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1064 if ((double)current_time() - (double)frames < 0.0) {
1068 set (current_time() - frames, true);
1071 ValueChanged (); /* EMIT_SIGNAL */
1085 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1087 if (session == 0) return FALSE;
1089 nframes_t frames = 0;
1091 switch (ev->direction) {
1094 frames = get_frames (field);
1096 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1099 set (current_time() + frames, true);
1100 ValueChanged (); /* EMIT_SIGNAL */
1104 case GDK_SCROLL_DOWN:
1105 frames = get_frames (field);
1107 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1111 if ((double)current_time() - (double)frames < 0.0) {
1114 set (current_time() - frames, true);
1117 ValueChanged (); /* EMIT_SIGNAL */
1130 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1132 if (session == 0 || !dragging) {
1136 float pixel_frame_scale_factor = 0.2f;
1139 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
1140 pixel_frame_scale_factor = 0.1f;
1144 if (Keyboard::modifier_state_contains (ev->state,
1145 Keyboard::Control|Keyboard::Alt)) {
1147 pixel_frame_scale_factor = 0.025f;
1150 double y_delta = ev->y - drag_y;
1152 drag_accum += y_delta*pixel_frame_scale_factor;
1156 if (trunc(drag_accum) != 0) {
1161 dir = (drag_accum < 0 ? 1:-1);
1162 pos = current_time();
1163 frames = get_frames (field,pos,dir);
1165 if (frames != 0 && frames * drag_accum < current_time()) {
1167 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1175 ValueChanged(); /* EMIT_SIGNAL */
1184 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1187 nframes_t frames = 0;
1191 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1194 frames = (nframes_t) floor (60.0 * session->frame_rate());
1197 frames = session->frame_rate();
1200 frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second());
1208 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1211 frames = (nframes_t) floor (60.0 * session->frame_rate());
1214 frames = session->frame_rate();
1221 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1227 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1233 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1241 AudioClock::current_time (nframes_t pos) const
1247 ret = smpte_frame_from_display ();
1250 ret = bbt_frame_from_display (pos);
1254 ret = minsec_frame_from_display ();
1258 ret = audio_frame_from_display ();
1269 AudioClock::current_duration (nframes_t pos) const
1275 ret = smpte_frame_from_display ();
1278 ret = bbt_frame_duration_from_display (pos);
1282 ret = minsec_frame_from_display ();
1286 ret = audio_frame_from_display ();
1297 AudioClock::smpte_sanitize_display()
1299 // Check SMPTE fields for sanity, possibly adjusting values
1300 if (atoi(minutes_label.get_text()) > 59) {
1301 minutes_label.set_text("59");
1304 if (atoi(seconds_label.get_text()) > 59) {
1305 seconds_label.set_text("59");
1308 switch ((long)rint(session->smpte_frames_per_second())) {
1310 if (atoi(frames_label.get_text()) > 23) {
1311 frames_label.set_text("23");
1315 if (atoi(frames_label.get_text()) > 24) {
1316 frames_label.set_text("24");
1320 if (atoi(frames_label.get_text()) > 29) {
1321 frames_label.set_text("29");
1328 if (session->smpte_drop_frames()) {
1329 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1330 frames_label.set_text("02");
1336 AudioClock::smpte_frame_from_display () const
1345 smpte.hours = atoi (hours_label.get_text());
1346 smpte.minutes = atoi (minutes_label.get_text());
1347 smpte.seconds = atoi (seconds_label.get_text());
1348 smpte.frames = atoi (frames_label.get_text());
1350 session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1354 #define SMPTE_SAMPLE_TEST_1
1355 #define SMPTE_SAMPLE_TEST_2
1356 #define SMPTE_SAMPLE_TEST_3
1357 #define SMPTE_SAMPLE_TEST_4
1358 #define SMPTE_SAMPLE_TEST_5
1359 #define SMPTE_SAMPLE_TEST_6
1360 #define SMPTE_SAMPLE_TEST_7
1362 // Testcode for smpte<->sample conversions (P.S.)
1365 nframes_t oldsample = 0;
1367 nframes_t sample_increment;
1369 sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1371 #ifdef SMPTE_SAMPLE_TEST_1
1372 // Test 1: use_offset = false, use_subframes = false
1373 cout << "use_offset = false, use_subframes = false" << endl;
1374 for (int i = 0; i < 108003; i++) {
1375 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1376 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1378 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1379 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1380 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1381 cout << "sample: " << sample1 << endl;
1382 cout << "sample: " << sample1 << " -> ";
1383 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1387 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1388 cout << "ERROR: smpte2 not equal smpte1" << endl;
1389 cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1390 cout << "sample: " << sample1 << endl;
1391 cout << "sample: " << sample1 << " -> ";
1392 cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1395 oldsample = sample1;
1396 session->smpte_increment( smpte1 );
1399 cout << "sample_increment: " << sample_increment << endl;
1400 cout << "sample: " << sample1 << " -> ";
1401 cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1404 #ifdef SMPTE_SAMPLE_TEST_2
1405 // Test 2: use_offset = true, use_subframes = false
1406 cout << "use_offset = true, use_subframes = false" << endl;
1412 smpte1.subframes = 0;
1413 sample1 = oldsample = 0;
1415 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1416 cout << "Starting at sample: " << sample1 << " -> ";
1417 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1419 for (int i = 0; i < 108003; i++) {
1420 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1421 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1423 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1424 // cout << "sample: " << sample1 << endl;
1425 // cout << "sample: " << sample1 << " -> ";
1426 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1428 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1429 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1430 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1431 cout << "sample: " << sample1 << endl;
1432 cout << "sample: " << sample1 << " -> ";
1433 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1437 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1438 cout << "ERROR: smpte2 not equal smpte1" << endl;
1439 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1440 cout << "sample: " << sample1 << endl;
1441 cout << "sample: " << sample1 << " -> ";
1442 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1445 oldsample = sample1;
1446 session->smpte_increment( smpte1 );
1449 cout << "sample_increment: " << sample_increment << endl;
1450 cout << "sample: " << sample1 << " -> ";
1451 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1454 #ifdef SMPTE_SAMPLE_TEST_3
1455 // Test 3: use_offset = true, use_subframes = false, decrement
1456 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1458 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1459 cout << "Starting at sample: " << sample1 << " -> ";
1460 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1462 for (int i = 0; i < 108003; i++) {
1463 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1464 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1466 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1467 // cout << "sample: " << sample1 << endl;
1468 // cout << "sample: " << sample1 << " -> ";
1469 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1471 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1472 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1473 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1474 cout << "sample: " << sample1 << endl;
1475 cout << "sample: " << sample1 << " -> ";
1476 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1480 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1481 cout << "ERROR: smpte2 not equal smpte1" << endl;
1482 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1483 cout << "sample: " << sample1 << endl;
1484 cout << "sample: " << sample1 << " -> ";
1485 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1488 oldsample = sample1;
1489 session->smpte_decrement( smpte1 );
1492 cout << "sample_decrement: " << sample_increment << endl;
1493 cout << "sample: " << sample1 << " -> ";
1494 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1498 #ifdef SMPTE_SAMPLE_TEST_4
1499 // Test 4: use_offset = true, use_subframes = true
1500 cout << "use_offset = true, use_subframes = true" << endl;
1502 for (long sub = 5; sub < 80; sub += 5) {
1507 smpte1.subframes = 0;
1508 sample1 = oldsample = (sample_increment * sub) / 80;
1510 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1512 cout << "starting at sample: " << sample1 << " -> ";
1513 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1515 for (int i = 0; i < 108003; i++) {
1516 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1517 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1519 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1520 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1521 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1522 cout << "sample: " << sample1 << endl;
1523 cout << "sample: " << sample1 << " -> ";
1524 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1528 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1529 cout << "ERROR: smpte2 not equal smpte1" << endl;
1530 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1531 cout << "sample: " << sample1 << endl;
1532 cout << "sample: " << sample1 << " -> ";
1533 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1536 oldsample = sample1;
1537 session->smpte_increment( smpte1 );
1540 cout << "sample_increment: " << sample_increment << endl;
1541 cout << "sample: " << sample1 << " -> ";
1542 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1544 for (int i = 0; i < 108003; i++) {
1545 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1546 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1548 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1549 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1550 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1551 cout << "sample: " << sample1 << endl;
1552 cout << "sample: " << sample1 << " -> ";
1553 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1557 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1558 cout << "ERROR: smpte2 not equal smpte1" << endl;
1559 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1560 cout << "sample: " << sample1 << endl;
1561 cout << "sample: " << sample1 << " -> ";
1562 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1565 oldsample = sample1;
1566 session->smpte_decrement( smpte1 );
1569 cout << "sample_decrement: " << sample_increment << endl;
1570 cout << "sample: " << sample1 << " -> ";
1571 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1576 #ifdef SMPTE_SAMPLE_TEST_5
1577 // Test 5: use_offset = true, use_subframes = false, increment seconds
1578 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1584 smpte1.subframes = 0;
1585 sample1 = oldsample = 0;
1586 sample_increment = session->frame_rate();
1588 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1589 cout << "Starting at sample: " << sample1 << " -> ";
1590 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1592 for (int i = 0; i < 3600; i++) {
1593 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1594 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1596 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1597 // cout << "sample: " << sample1 << endl;
1598 // cout << "sample: " << sample1 << " -> ";
1599 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1601 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1603 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1607 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1608 cout << "ERROR: smpte2 not equal smpte1" << endl;
1609 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1610 cout << "sample: " << sample1 << endl;
1611 cout << "sample: " << sample1 << " -> ";
1612 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1615 oldsample = sample1;
1616 session->smpte_increment_seconds( smpte1 );
1619 cout << "sample_increment: " << sample_increment << endl;
1620 cout << "sample: " << sample1 << " -> ";
1621 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1625 #ifdef SMPTE_SAMPLE_TEST_6
1626 // Test 6: use_offset = true, use_subframes = false, increment minutes
1627 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1633 smpte1.subframes = 0;
1634 sample1 = oldsample = 0;
1635 sample_increment = session->frame_rate() * 60;
1637 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1638 cout << "Starting at sample: " << sample1 << " -> ";
1639 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1641 for (int i = 0; i < 60; i++) {
1642 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1643 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1645 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1646 // cout << "sample: " << sample1 << endl;
1647 // cout << "sample: " << sample1 << " -> ";
1648 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1650 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1652 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1656 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1657 cout << "ERROR: smpte2 not equal smpte1" << endl;
1658 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1659 cout << "sample: " << sample1 << endl;
1660 cout << "sample: " << sample1 << " -> ";
1661 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1664 oldsample = sample1;
1665 session->smpte_increment_minutes( smpte1 );
1668 cout << "sample_increment: " << sample_increment << endl;
1669 cout << "sample: " << sample1 << " -> ";
1670 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1673 #ifdef SMPTE_SAMPLE_TEST_7
1674 // Test 7: use_offset = true, use_subframes = false, increment hours
1675 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1681 smpte1.subframes = 0;
1682 sample1 = oldsample = 0;
1683 sample_increment = session->frame_rate() * 60 * 60;
1685 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1686 cout << "Starting at sample: " << sample1 << " -> ";
1687 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1689 for (int i = 0; i < 10; i++) {
1690 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1691 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1693 // cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1694 // cout << "sample: " << sample1 << endl;
1695 // cout << "sample: " << sample1 << " -> ";
1696 // cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1698 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1700 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1704 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1705 cout << "ERROR: smpte2 not equal smpte1" << endl;
1706 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1707 cout << "sample: " << sample1 << endl;
1708 cout << "sample: " << sample1 << " -> ";
1709 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1712 oldsample = sample1;
1713 session->smpte_increment_hours( smpte1 );
1716 cout << "sample_increment: " << sample_increment << endl;
1717 cout << "sample: " << sample1 << " -> ";
1718 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1727 AudioClock::minsec_frame_from_display () const
1733 int hrs = atoi (ms_hours_label.get_text());
1734 int mins = atoi (ms_minutes_label.get_text());
1735 float secs = atof (ms_seconds_label.get_text());
1737 nframes_t sr = session->frame_rate();
1739 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1743 AudioClock::bbt_frame_from_display (nframes_t pos) const
1746 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1751 any.type = AnyTime::BBT;
1753 any.bbt.bars = atoi (bars_label.get_text());
1754 any.bbt.beats = atoi (beats_label.get_text());
1755 any.bbt.ticks = atoi (ticks_label.get_text());
1757 nframes_t ret = session->convert_to_frames_at (pos, any);
1764 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1767 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1774 bbt.bars = atoi (bars_label.get_text());
1775 bbt.beats = atoi (beats_label.get_text());
1776 bbt.ticks = atoi (ticks_label.get_text());
1778 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1782 AudioClock::audio_frame_from_display () const
1784 return (nframes_t) atoi (audio_frames_label.get_text());
1788 AudioClock::build_ops_menu ()
1790 using namespace Menu_Helpers;
1791 ops_menu = new Menu;
1792 MenuList& ops_items = ops_menu->items();
1793 ops_menu->set_name ("ArdourContextMenu");
1795 Menu *mode_menu = manage (new Menu);
1796 MenuList& mode_items = mode_menu->items();
1797 mode_menu->set_name ("ArdourContextMenu");
1799 mode_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1800 mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1801 mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1802 mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1803 mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1805 ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1809 AudioClock::set_mode (Mode m)
1811 /* slightly tricky: this is called from within the ARDOUR_UI
1812 constructor by some of its clock members. at that time
1813 the instance pointer is unset, so we have to be careful.
1814 the main idea is to drop keyboard focus in case we had
1815 started editing the clock and then we switch clock mode.
1818 clock_base.grab_focus ();
1828 clock_base.remove ();
1838 clock_base.add (smpte_packer_hbox);
1842 clock_base.add (bbt_packer_hbox);
1846 clock_base.add (minsec_packer_hbox);
1850 clock_base.add (frames_packer_hbox);
1857 set_size_requests ();
1859 set (last_when, true);
1860 clock_base.show_all ();
1861 key_entry_state = 0;
1865 AudioClock::set_size_requests ()
1867 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
1871 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
1872 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
1873 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
1874 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
1878 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
1879 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
1880 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
1884 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
1885 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
1886 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
1890 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);