2 Copyright (C) 1999 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <cstdio> // for sprintf
23 #include "pbd/convert.h"
24 #include "pbd/enumwriter.h"
26 #include <gtkmm2ext/utils.h>
28 #include "ardour/ardour.h"
29 #include "ardour/session.h"
30 #include "ardour/tempo.h"
31 #include "ardour/profile.h"
32 #include <sigc++/bind.h>
34 #include "ardour_ui.h"
35 #include "audio_clock.h"
40 using namespace ARDOUR;
45 using Gtkmm2ext::Keyboard;
50 sigc::signal<void> AudioClock::ModeChanged;
51 vector<AudioClock*> AudioClock::clocks;
53 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
54 2, /* Timecode_Hours */
55 2, /* Timecode_Minutes */
56 2, /* Timecode_Seconds */
57 2, /* Timecode_Frames */
67 AudioClock::AudioClock (std::string clock_name, bool transient, std::string widget_name,
68 bool allow_edit, bool follows_playhead, bool duration, bool with_info)
70 is_transient (transient),
71 is_duration (duration),
72 editable (allow_edit),
73 _follows_playhead (follows_playhead),
89 bbt_reference_time = -1;
92 frames_upper_info_label = manage (new Label);
93 frames_lower_info_label = manage (new Label);
94 timecode_upper_info_label = manage (new Label);
95 timecode_lower_info_label = manage (new Label);
96 bbt_upper_info_label = manage (new Label);
97 bbt_lower_info_label = manage (new Label);
99 frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
100 frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
101 timecode_upper_info_label->set_name ("AudioClockTimecodeUpperInfo");
102 timecode_lower_info_label->set_name ("AudioClockTimecodeLowerInfo");
103 bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
104 bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
106 Gtkmm2ext::set_size_request_to_display_given_text(*timecode_upper_info_label, "23.98",0,0);
107 Gtkmm2ext::set_size_request_to_display_given_text(*timecode_lower_info_label, "NDF",0,0);
109 Gtkmm2ext::set_size_request_to_display_given_text(*bbt_upper_info_label, "88|88",0,0);
110 Gtkmm2ext::set_size_request_to_display_given_text(*bbt_lower_info_label, "888.88",0,0);
112 frames_info_box.pack_start (*frames_upper_info_label, true, true);
113 frames_info_box.pack_start (*frames_lower_info_label, true, true);
114 timecode_info_box.pack_start (*timecode_upper_info_label, true, true);
115 timecode_info_box.pack_start (*timecode_lower_info_label, true, true);
116 bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
117 bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
120 frames_upper_info_label = 0;
121 frames_lower_info_label = 0;
122 timecode_upper_info_label = 0;
123 timecode_lower_info_label = 0;
124 bbt_upper_info_label = 0;
125 bbt_lower_info_label = 0;
128 audio_frames_ebox.add (audio_frames_label);
130 frames_packer.set_homogeneous (false);
131 frames_packer.set_border_width (2);
132 frames_packer.pack_start (audio_frames_ebox, false, false);
135 frames_packer.pack_start (frames_info_box, false, false, 5);
138 frames_packer_hbox.pack_start (frames_packer, true, false);
140 hours_ebox.add (hours_label);
141 minutes_ebox.add (minutes_label);
142 seconds_ebox.add (seconds_label);
143 frames_ebox.add (frames_label);
144 bars_ebox.add (bars_label);
145 beats_ebox.add (beats_label);
146 ticks_ebox.add (ticks_label);
147 ms_hours_ebox.add (ms_hours_label);
148 ms_minutes_ebox.add (ms_minutes_label);
149 ms_seconds_ebox.add (ms_seconds_label);
151 timecode_packer.set_homogeneous (false);
152 timecode_packer.set_border_width (2);
153 timecode_packer.pack_start (hours_ebox, false, false);
154 timecode_packer.pack_start (colon1, false, false);
155 timecode_packer.pack_start (minutes_ebox, false, false);
156 timecode_packer.pack_start (colon2, false, false);
157 timecode_packer.pack_start (seconds_ebox, false, false);
158 timecode_packer.pack_start (colon3, false, false);
159 timecode_packer.pack_start (frames_ebox, false, false);
162 timecode_packer.pack_start (timecode_info_box, false, false, 5);
165 timecode_packer_hbox.pack_start (timecode_packer, true, false);
167 bbt_packer.set_homogeneous (false);
168 bbt_packer.set_border_width (2);
169 bbt_packer.pack_start (bars_ebox, false, false);
170 bbt_packer.pack_start (b1, false, false);
171 bbt_packer.pack_start (beats_ebox, false, false);
172 bbt_packer.pack_start (b2, false, false);
173 bbt_packer.pack_start (ticks_ebox, false, false);
176 bbt_packer.pack_start (bbt_info_box, false, false, 5);
179 bbt_packer_hbox.pack_start (bbt_packer, true, false);
181 minsec_packer.set_homogeneous (false);
182 minsec_packer.set_border_width (2);
183 minsec_packer.pack_start (ms_hours_ebox, false, false);
184 minsec_packer.pack_start (colon4, false, false);
185 minsec_packer.pack_start (ms_minutes_ebox, false, false);
186 minsec_packer.pack_start (colon5, false, false);
187 minsec_packer.pack_start (ms_seconds_ebox, false, false);
189 minsec_packer_hbox.pack_start (minsec_packer, true, false);
191 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
192 clock_frame.set_name ("BaseFrame");
194 clock_frame.add (clock_base);
196 set_widget_name (widget_name);
198 _mode = BBT; /* lie to force mode switch */
201 pack_start (clock_frame, true, true);
203 /* the clock base handles button releases for menu popup regardless of
204 editable status. if the clock is editable, the clock base is where
205 we pass focus to after leaving the last editable "field", which
206 will then shutdown editing till the user starts it up again.
208 it does this because the focus out event on the field disables
209 keyboard event handling, and we don't connect anything up to
210 notice focus in on the clock base. hence, keyboard event handling
214 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
215 clock_base.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &AudioClock::field_button_release_event), Timecode_Hours));
217 Session::TimecodeOffsetChanged.connect (_session_connections, sigc::mem_fun (*this, &AudioClock::timecode_offset_changed));
223 set (last_when, true);
226 clocks.push_back (this);
231 AudioClock::set_widget_name (string name)
233 Widget::set_name (name);
235 clock_base.set_name (name);
237 audio_frames_label.set_name (name);
238 hours_label.set_name (name);
239 minutes_label.set_name (name);
240 seconds_label.set_name (name);
241 frames_label.set_name (name);
242 bars_label.set_name (name);
243 beats_label.set_name (name);
244 ticks_label.set_name (name);
245 ms_hours_label.set_name (name);
246 ms_minutes_label.set_name (name);
247 ms_seconds_label.set_name (name);
248 hours_ebox.set_name (name);
249 minutes_ebox.set_name (name);
250 seconds_ebox.set_name (name);
251 frames_ebox.set_name (name);
252 audio_frames_ebox.set_name (name);
253 bars_ebox.set_name (name);
254 beats_ebox.set_name (name);
255 ticks_ebox.set_name (name);
256 ms_hours_ebox.set_name (name);
257 ms_minutes_ebox.set_name (name);
258 ms_seconds_ebox.set_name (name);
260 colon1.set_name (name);
261 colon2.set_name (name);
262 colon3.set_name (name);
263 colon4.set_name (name);
264 colon5.set_name (name);
272 AudioClock::setup_events ()
274 clock_base.set_flags (Gtk::CAN_FOCUS);
276 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);
277 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);
278 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);
279 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 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);
281 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);
282 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);
283 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);
284 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);
285 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);
286 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);
288 hours_ebox.set_flags (Gtk::CAN_FOCUS);
289 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
290 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
291 frames_ebox.set_flags (Gtk::CAN_FOCUS);
292 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
293 bars_ebox.set_flags (Gtk::CAN_FOCUS);
294 beats_ebox.set_flags (Gtk::CAN_FOCUS);
295 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
296 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
297 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
298 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
300 hours_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Hours));
301 minutes_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Minutes));
302 seconds_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Seconds));
303 frames_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Frames));
304 audio_frames_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
305 bars_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
306 beats_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
307 ticks_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
308 ms_hours_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
309 ms_minutes_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
310 ms_seconds_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
312 hours_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Hours));
313 minutes_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Minutes));
314 seconds_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Seconds));
315 frames_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Frames));
316 audio_frames_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
317 bars_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Bars));
318 beats_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Beats));
319 ticks_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
320 ms_hours_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
321 ms_minutes_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
322 ms_seconds_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
324 hours_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Hours));
325 minutes_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Minutes));
326 seconds_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Seconds));
327 frames_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Frames));
328 audio_frames_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
329 bars_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Bars));
330 beats_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Beats));
331 ticks_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
332 ms_hours_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
333 ms_minutes_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
334 ms_seconds_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
336 hours_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Hours));
337 minutes_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Minutes));
338 seconds_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Seconds));
339 frames_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Frames));
340 audio_frames_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
341 bars_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
342 beats_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
343 ticks_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
344 ms_hours_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
345 ms_minutes_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
346 ms_seconds_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
348 hours_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Hours));
349 minutes_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Minutes));
350 seconds_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Seconds));
351 frames_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Frames));
352 audio_frames_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), AudioFrames));
353 bars_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Bars));
354 beats_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Beats));
355 ticks_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Ticks));
356 ms_hours_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), MS_Hours));
357 ms_minutes_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), MS_Minutes));
358 ms_seconds_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), MS_Seconds));
360 hours_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Hours));
361 minutes_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Minutes));
362 seconds_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Seconds));
363 frames_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Frames));
364 audio_frames_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
365 bars_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Bars));
366 beats_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Beats));
367 ticks_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
368 ms_hours_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
369 ms_minutes_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
370 ms_seconds_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
372 hours_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Hours));
373 minutes_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Minutes));
374 seconds_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Seconds));
375 frames_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Frames));
376 audio_frames_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
377 bars_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
378 beats_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
379 ticks_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
380 ms_hours_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
381 ms_minutes_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
382 ms_seconds_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
384 hours_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Hours));
385 minutes_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Minutes));
386 seconds_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Seconds));
387 frames_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Frames));
388 audio_frames_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
389 bars_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
390 beats_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
391 ticks_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
392 ms_hours_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
393 ms_minutes_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
394 ms_seconds_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
396 clock_base.signal_focus_in_event().connect (sigc::mem_fun (*this, &AudioClock::drop_focus_handler));
400 AudioClock::drop_focus_handler (GdkEventFocus*)
402 Keyboard::magic_widget_drop_focus ();
407 AudioClock::on_realize ()
411 /* styles are not available until the widgets are bound to a window */
413 set_size_requests ();
417 AudioClock::set (nframes_t when, bool force, nframes_t offset, char which)
420 if ((!force && !is_visible()) || _session == 0) {
424 if (when == last_when && !offset && !force) {
428 bool pdelta = Config->get_primary_clock_delta_edit_cursor();
429 bool sdelta = Config->get_secondary_clock_delta_edit_cursor();
431 if (offset && which == 'p' && pdelta) {
432 when = (when > offset) ? when - offset : offset - when;
433 } else if (offset && which == 's' && sdelta) {
434 when = (when > offset) ? when - offset : offset - when;
437 if (which == 'p' && pdelta && !last_pdelta) {
438 set_widget_name("TransportClockDisplayDelta");
440 } else if (which == 'p' && !pdelta && last_pdelta) {
441 set_widget_name("TransportClockDisplay");
443 } else if (which == 's' && sdelta && !last_sdelta) {
444 set_widget_name("SecondaryClockDisplayDelta");
446 } else if (which == 's' && !sdelta && last_sdelta) {
447 set_widget_name("SecondaryClockDisplay");
453 set_timecode (when, force);
457 set_bbt (when, force);
461 set_minsec (when, force);
465 set_frames (when, force);
476 AudioClock::timecode_offset_changed ()
483 current = current_duration();
485 current = current_time ();
495 AudioClock::set_frames (nframes_t when, bool /*force*/)
498 snprintf (buf, sizeof (buf), "%u", when);
499 audio_frames_label.set_text (buf);
501 if (frames_upper_info_label) {
502 nframes_t rate = _session->frame_rate();
504 if (fmod (rate, 1000.0) == 0.000) {
505 sprintf (buf, "%uK", rate/1000);
507 sprintf (buf, "%.3fK", rate/1000.0f);
510 if (frames_upper_info_label->get_text() != buf) {
511 frames_upper_info_label->set_text (buf);
514 float vid_pullup = _session->config.get_video_pullup();
516 if (vid_pullup == 0.0) {
517 if (frames_lower_info_label->get_text () != _("none")) {
518 frames_lower_info_label->set_text(_("none"));
521 sprintf (buf, "%-6.4f", vid_pullup);
522 if (frames_lower_info_label->get_text() != buf) {
523 frames_lower_info_label->set_text (buf);
530 AudioClock::set_minsec (nframes_t when, bool force)
539 hrs = (int) floor (left / (_session->frame_rate() * 60.0f * 60.0f));
540 left -= (nframes_t) floor (hrs * _session->frame_rate() * 60.0f * 60.0f);
541 mins = (int) floor (left / (_session->frame_rate() * 60.0f));
542 left -= (nframes_t) floor (mins * _session->frame_rate() * 60.0f);
543 secs = left / (float) _session->frame_rate();
545 if (force || hrs != ms_last_hrs) {
546 sprintf (buf, "%02d", hrs);
547 ms_hours_label.set_text (buf);
551 if (force || mins != ms_last_mins) {
552 sprintf (buf, "%02d", mins);
553 ms_minutes_label.set_text (buf);
557 if (force || secs != ms_last_secs) {
558 sprintf (buf, "%06.3f", secs);
559 ms_seconds_label.set_text (buf);
565 AudioClock::set_timecode (nframes_t when, bool force)
568 Timecode::Time timecode;
571 _session->timecode_duration (when, timecode);
573 _session->timecode_time (when, timecode);
576 if (force || timecode.hours != last_hrs || timecode.negative != last_negative) {
577 if (timecode.negative) {
578 sprintf (buf, "-%02" PRIu32, timecode.hours);
580 sprintf (buf, " %02" PRIu32, timecode.hours);
582 hours_label.set_text (buf);
583 last_hrs = timecode.hours;
584 last_negative = timecode.negative;
587 if (force || timecode.minutes != last_mins) {
588 sprintf (buf, "%02" PRIu32, timecode.minutes);
589 minutes_label.set_text (buf);
590 last_mins = timecode.minutes;
593 if (force || timecode.seconds != last_secs) {
594 sprintf (buf, "%02" PRIu32, timecode.seconds);
595 seconds_label.set_text (buf);
596 last_secs = timecode.seconds;
599 if (force || timecode.frames != last_frames) {
600 sprintf (buf, "%02" PRIu32, timecode.frames);
601 frames_label.set_text (buf);
602 last_frames = timecode.frames;
605 if (timecode_upper_info_label) {
606 double timecode_frames = _session->timecode_frames_per_second();
608 if ( fmod(timecode_frames, 1.0) == 0.0) {
609 sprintf (buf, "%u", int (timecode_frames));
611 sprintf (buf, "%.2f", timecode_frames);
614 if (timecode_upper_info_label->get_text() != buf) {
615 timecode_upper_info_label->set_text (buf);
618 if ((fabs(timecode_frames - 29.97) < 0.0001) || timecode_frames == 30) {
619 if (_session->timecode_drop_frames()) {
622 sprintf (buf, "NDF");
625 // there is no drop frame alternative
629 if (timecode_lower_info_label->get_text() != buf) {
630 timecode_lower_info_label->set_text (buf);
636 AudioClock::set_bbt (nframes_t when, bool force)
641 /* handle a common case */
648 _session->tempo_map().bbt_time (when, bbt);
653 _session->tempo_map().bbt_time (when, bbt);
656 sprintf (buf, "%03" PRIu32, bbt.bars);
657 if (force || bars_label.get_text () != buf) {
658 bars_label.set_text (buf);
660 sprintf (buf, "%02" PRIu32, bbt.beats);
661 if (force || beats_label.get_text () != buf) {
662 beats_label.set_text (buf);
664 sprintf (buf, "%04" PRIu32, bbt.ticks);
665 if (force || ticks_label.get_text () != buf) {
666 ticks_label.set_text (buf);
669 if (bbt_upper_info_label) {
672 if (bbt_reference_time < 0) {
675 pos = bbt_reference_time;
678 TempoMetric m (_session->tempo_map().metric_at (pos));
680 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
681 if (bbt_lower_info_label->get_text() != buf) {
682 bbt_lower_info_label->set_text (buf);
684 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
685 if (bbt_upper_info_label->get_text() != buf) {
686 bbt_upper_info_label->set_text (buf);
692 AudioClock::set_session (Session *s)
694 SessionHandlePtr::set_session (s);
699 XMLNode* node = _session->extra_xml (X_("ClockModes"));
700 AudioClock::Mode amode;
703 if ((prop = node->property (_name)) != 0) {
704 amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
709 set (last_when, true);
718 hours_ebox.grab_focus ();
722 bars_ebox.grab_focus ();
726 ms_hours_ebox.grab_focus ();
730 frames_ebox.grab_focus ();
740 AudioClock::field_key_press_event (GdkEventKey */*ev*/, Field /*field*/)
742 /* all key activity is handled on key release */
747 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
752 bool move_on = false;
756 label = &hours_label;
758 case Timecode_Minutes:
759 label = &minutes_label;
761 case Timecode_Seconds:
762 label = &seconds_label;
764 case Timecode_Frames:
765 label = &frames_label;
769 label = &audio_frames_label;
773 label = &ms_hours_label;
776 label = &ms_minutes_label;
779 label = &ms_seconds_label;
786 label = &beats_label;
789 label = &ticks_label;
795 switch (ev->keyval) {
839 if (_mode == MinSec && field == MS_Seconds) {
854 clock_base.grab_focus ();
855 ChangeAborted(); /* EMIT SIGNAL */
864 if (key_entry_state == 0) {
866 /* initialize with a fresh new string */
868 if (field != AudioFrames) {
869 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
878 string existing = label->get_text();
879 if (existing.length() >= field_length[field]) {
880 new_text = existing.substr (1, field_length[field] - 1);
882 new_text = existing.substr (0, field_length[field] - 1);
886 new_text += new_char;
887 label->set_text (new_text);
891 if (key_entry_state == field_length[field]) {
897 if (key_entry_state) {
901 case Timecode_Minutes:
902 case Timecode_Seconds:
903 case Timecode_Frames:
904 // Check Timecode fields for sanity (may also adjust fields)
905 timecode_sanitize_display();
910 // Bars should never be, unless this clock is for a duration
911 if (atoi(bars_label.get_text()) == 0 && !is_duration) {
912 bars_label.set_text("001");
914 // beats should never be 0, unless this clock is for a duration
915 if (atoi(beats_label.get_text()) == 0 && !is_duration) {
916 beats_label.set_text("01");
923 ValueChanged(); /* EMIT_SIGNAL */
926 /* move on to the next field.
934 minutes_ebox.grab_focus ();
936 case Timecode_Minutes:
937 seconds_ebox.grab_focus ();
939 case Timecode_Seconds:
940 frames_ebox.grab_focus ();
942 case Timecode_Frames:
943 clock_base.grab_focus ();
948 clock_base.grab_focus ();
954 ms_minutes_ebox.grab_focus ();
957 ms_seconds_ebox.grab_focus ();
960 clock_base.grab_focus ();
966 beats_ebox.grab_focus ();
969 ticks_ebox.grab_focus ();
972 clock_base.grab_focus ();
981 //if user hit Enter, lose focus
982 switch (ev->keyval) {
985 clock_base.grab_focus ();
992 AudioClock::field_focus_in_event (GdkEventFocus */*ev*/, Field field)
996 Keyboard::magic_widget_grab_focus ();
1000 hours_ebox.set_flags (Gtk::HAS_FOCUS);
1001 hours_ebox.set_state (Gtk::STATE_ACTIVE);
1003 case Timecode_Minutes:
1004 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
1005 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
1007 case Timecode_Seconds:
1008 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
1009 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
1011 case Timecode_Frames:
1012 frames_ebox.set_flags (Gtk::HAS_FOCUS);
1013 frames_ebox.set_state (Gtk::STATE_ACTIVE);
1017 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
1018 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
1022 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
1023 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
1026 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
1027 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
1030 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
1031 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
1034 bars_ebox.set_flags (Gtk::HAS_FOCUS);
1035 bars_ebox.set_state (Gtk::STATE_ACTIVE);
1038 beats_ebox.set_flags (Gtk::HAS_FOCUS);
1039 beats_ebox.set_state (Gtk::STATE_ACTIVE);
1042 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
1043 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
1051 AudioClock::field_focus_out_event (GdkEventFocus */*ev*/, Field field)
1055 case Timecode_Hours:
1056 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1057 hours_ebox.set_state (Gtk::STATE_NORMAL);
1059 case Timecode_Minutes:
1060 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1061 minutes_ebox.set_state (Gtk::STATE_NORMAL);
1063 case Timecode_Seconds:
1064 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1065 seconds_ebox.set_state (Gtk::STATE_NORMAL);
1067 case Timecode_Frames:
1068 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1069 frames_ebox.set_state (Gtk::STATE_NORMAL);
1073 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1074 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
1078 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1079 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
1082 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1083 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
1086 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1087 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1091 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1092 bars_ebox.set_state (Gtk::STATE_NORMAL);
1095 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1096 beats_ebox.set_state (Gtk::STATE_NORMAL);
1099 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1100 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1104 Keyboard::magic_widget_drop_focus ();
1110 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1113 cerr << "button event on clock but we are dragging\n";
1114 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1116 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
1117 // we actually dragged so return without setting editing focus, or we shift clicked
1123 if (ops_menu == 0) {
1126 ops_menu->popup (1, ev->time);
1130 if (Keyboard::is_context_menu_event (ev)) {
1131 cerr << "Context menu event on clock\n";
1132 if (ops_menu == 0) {
1135 ops_menu->popup (1, ev->time);
1139 switch (ev->button) {
1142 case Timecode_Hours:
1143 hours_ebox.grab_focus();
1145 case Timecode_Minutes:
1146 minutes_ebox.grab_focus();
1148 case Timecode_Seconds:
1149 seconds_ebox.grab_focus();
1151 case Timecode_Frames:
1152 frames_ebox.grab_focus();
1156 audio_frames_ebox.grab_focus();
1160 ms_hours_ebox.grab_focus();
1163 ms_minutes_ebox.grab_focus();
1166 ms_seconds_ebox.grab_focus();
1170 bars_ebox.grab_focus ();
1173 beats_ebox.grab_focus ();
1176 ticks_ebox.grab_focus ();
1189 AudioClock::field_button_press_event (GdkEventButton *ev, Field /*field*/)
1191 if (_session == 0) {
1195 nframes_t frames = 0;
1197 switch (ev->button) {
1199 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1201 ValueChanged (); /* EMIT_SIGNAL */
1204 /* make absolutely sure that the pointer is grabbed */
1205 gdk_pointer_grab(ev->window,false ,
1206 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1207 NULL,NULL,ev->time);
1210 drag_start_y = ev->y;
1215 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1217 ValueChanged (); /* EMIT_SIGNAL */
1222 /* used for context sensitive menu */
1235 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1237 if (_session == 0) {
1241 nframes_t frames = 0;
1243 switch (ev->direction) {
1246 frames = get_frames (field);
1248 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1251 set (current_time() + frames, true);
1252 ValueChanged (); /* EMIT_SIGNAL */
1256 case GDK_SCROLL_DOWN:
1257 frames = get_frames (field);
1259 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1263 if ((double)current_time() - (double)frames < 0.0) {
1266 set (current_time() - frames, true);
1269 ValueChanged (); /* EMIT_SIGNAL */
1282 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1284 if (_session == 0 || !dragging) {
1288 float pixel_frame_scale_factor = 0.2f;
1291 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1292 pixel_frame_scale_factor = 0.1f;
1296 if (Keyboard::modifier_state_contains (ev->state,
1297 Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) {
1299 pixel_frame_scale_factor = 0.025f;
1302 double y_delta = ev->y - drag_y;
1304 drag_accum += y_delta*pixel_frame_scale_factor;
1308 if (trunc(drag_accum) != 0) {
1313 dir = (drag_accum < 0 ? 1:-1);
1314 pos = current_time();
1315 frames = get_frames (field,pos,dir);
1317 if (frames != 0 && frames * drag_accum < current_time()) {
1319 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1327 ValueChanged(); /* EMIT_SIGNAL */
1336 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1339 nframes_t frames = 0;
1342 case Timecode_Hours:
1343 frames = (nframes_t) floor (3600.0 * _session->frame_rate());
1345 case Timecode_Minutes:
1346 frames = (nframes_t) floor (60.0 * _session->frame_rate());
1348 case Timecode_Seconds:
1349 frames = _session->frame_rate();
1351 case Timecode_Frames:
1352 frames = (nframes_t) floor (_session->frame_rate() / _session->timecode_frames_per_second());
1360 frames = (nframes_t) floor (3600.0 * _session->frame_rate());
1363 frames = (nframes_t) floor (60.0 * _session->frame_rate());
1366 frames = _session->frame_rate();
1373 frames = _session->tempo_map().bbt_duration_at(pos,bbt,dir);
1379 frames = _session->tempo_map().bbt_duration_at(pos,bbt,dir);
1385 frames = _session->tempo_map().bbt_duration_at(pos,bbt,dir);
1393 AudioClock::current_time (nframes_t pos) const
1399 ret = timecode_frame_from_display ();
1402 ret = bbt_frame_from_display (pos);
1406 ret = minsec_frame_from_display ();
1410 ret = audio_frame_from_display ();
1421 AudioClock::current_duration (nframes_t pos) const
1427 ret = timecode_frame_from_display ();
1430 ret = bbt_frame_duration_from_display (pos);
1434 ret = minsec_frame_from_display ();
1438 ret = audio_frame_from_display ();
1449 AudioClock::timecode_sanitize_display()
1451 // Check Timecode fields for sanity, possibly adjusting values
1452 if (atoi(minutes_label.get_text()) > 59) {
1453 minutes_label.set_text("59");
1456 if (atoi(seconds_label.get_text()) > 59) {
1457 seconds_label.set_text("59");
1460 switch ((long)rint(_session->timecode_frames_per_second())) {
1462 if (atoi(frames_label.get_text()) > 23) {
1463 frames_label.set_text("23");
1467 if (atoi(frames_label.get_text()) > 24) {
1468 frames_label.set_text("24");
1472 if (atoi(frames_label.get_text()) > 29) {
1473 frames_label.set_text("29");
1480 if (_session->timecode_drop_frames()) {
1481 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1482 frames_label.set_text("02");
1488 AudioClock::timecode_frame_from_display () const
1490 if (_session == 0) {
1494 Timecode::Time timecode;
1497 timecode.hours = atoi (hours_label.get_text());
1498 timecode.minutes = atoi (minutes_label.get_text());
1499 timecode.seconds = atoi (seconds_label.get_text());
1500 timecode.frames = atoi (frames_label.get_text());
1501 timecode.rate = _session->timecode_frames_per_second();
1502 timecode.drop= _session->timecode_drop_frames();
1504 _session->timecode_to_sample( timecode, sample, false /* use_offset */, false /* use_subframes */ );
1508 #define Timecode_SAMPLE_TEST_1
1509 #define Timecode_SAMPLE_TEST_2
1510 #define Timecode_SAMPLE_TEST_3
1511 #define Timecode_SAMPLE_TEST_4
1512 #define Timecode_SAMPLE_TEST_5
1513 #define Timecode_SAMPLE_TEST_6
1514 #define Timecode_SAMPLE_TEST_7
1516 // Testcode for timecode<->sample conversions (P.S.)
1517 Timecode::Time timecode1;
1519 nframes_t oldsample = 0;
1520 Timecode::Time timecode2;
1521 nframes_t sample_increment;
1523 sample_increment = (long)rint(_session->frame_rate() / _session->timecode_frames_per_second);
1525 #ifdef Timecode_SAMPLE_TEST_1
1526 // Test 1: use_offset = false, use_subframes = false
1527 cout << "use_offset = false, use_subframes = false" << endl;
1528 for (int i = 0; i < 108003; i++) {
1529 _session->timecode_to_sample( timecode1, sample1, false /* use_offset */, false /* use_subframes */ );
1530 _session->sample_to_timecode( sample1, timecode2, false /* use_offset */, false /* use_subframes */ );
1532 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1533 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1534 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1535 cout << "sample: " << sample1 << endl;
1536 cout << "sample: " << sample1 << " -> ";
1537 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1541 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1542 cout << "ERROR: timecode2 not equal timecode1" << endl;
1543 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1544 cout << "sample: " << sample1 << endl;
1545 cout << "sample: " << sample1 << " -> ";
1546 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1549 oldsample = sample1;
1550 _session->timecode_increment( timecode1 );
1553 cout << "sample_increment: " << sample_increment << endl;
1554 cout << "sample: " << sample1 << " -> ";
1555 cout << "timecode: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1558 #ifdef Timecode_SAMPLE_TEST_2
1559 // Test 2: use_offset = true, use_subframes = false
1560 cout << "use_offset = true, use_subframes = false" << endl;
1562 timecode1.hours = 0;
1563 timecode1.minutes = 0;
1564 timecode1.seconds = 0;
1565 timecode1.frames = 0;
1566 timecode1.subframes = 0;
1567 sample1 = oldsample = 0;
1569 _session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1570 cout << "Starting at sample: " << sample1 << " -> ";
1571 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1573 for (int i = 0; i < 108003; i++) {
1574 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1575 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1577 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1578 // cout << "sample: " << sample1 << endl;
1579 // cout << "sample: " << sample1 << " -> ";
1580 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1582 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1583 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1584 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1585 cout << "sample: " << sample1 << endl;
1586 cout << "sample: " << sample1 << " -> ";
1587 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1591 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1592 cout << "ERROR: timecode2 not equal timecode1" << endl;
1593 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1594 cout << "sample: " << sample1 << endl;
1595 cout << "sample: " << sample1 << " -> ";
1596 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1599 oldsample = sample1;
1600 _session->timecode_increment( timecode1 );
1603 cout << "sample_increment: " << sample_increment << endl;
1604 cout << "sample: " << sample1 << " -> ";
1605 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1608 #ifdef Timecode_SAMPLE_TEST_3
1609 // Test 3: use_offset = true, use_subframes = false, decrement
1610 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1612 _session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1613 cout << "Starting at sample: " << sample1 << " -> ";
1614 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1616 for (int i = 0; i < 108003; i++) {
1617 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1618 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1620 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1621 // cout << "sample: " << sample1 << endl;
1622 // cout << "sample: " << sample1 << " -> ";
1623 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1625 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1626 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1627 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1628 cout << "sample: " << sample1 << endl;
1629 cout << "sample: " << sample1 << " -> ";
1630 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1634 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1635 cout << "ERROR: timecode2 not equal timecode1" << endl;
1636 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1637 cout << "sample: " << sample1 << endl;
1638 cout << "sample: " << sample1 << " -> ";
1639 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1642 oldsample = sample1;
1643 _session->timecode_decrement( timecode1 );
1646 cout << "sample_decrement: " << sample_increment << endl;
1647 cout << "sample: " << sample1 << " -> ";
1648 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1652 #ifdef Timecode_SAMPLE_TEST_4
1653 // Test 4: use_offset = true, use_subframes = true
1654 cout << "use_offset = true, use_subframes = true" << endl;
1656 for (long sub = 5; sub < 80; sub += 5) {
1657 timecode1.hours = 0;
1658 timecode1.minutes = 0;
1659 timecode1.seconds = 0;
1660 timecode1.frames = 0;
1661 timecode1.subframes = 0;
1662 sample1 = oldsample = (sample_increment * sub) / 80;
1664 _session->sample_to_timecode( sample1, timecode1, true /* use_offset */, true /* use_subframes */ );
1666 cout << "starting at sample: " << sample1 << " -> ";
1667 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1669 for (int i = 0; i < 108003; i++) {
1670 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1671 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1673 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1674 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1675 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1676 cout << "sample: " << sample1 << endl;
1677 cout << "sample: " << sample1 << " -> ";
1678 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1682 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1683 cout << "ERROR: timecode2 not equal timecode1" << endl;
1684 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1685 cout << "sample: " << sample1 << endl;
1686 cout << "sample: " << sample1 << " -> ";
1687 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1690 oldsample = sample1;
1691 _session->timecode_increment( timecode1 );
1694 cout << "sample_increment: " << sample_increment << endl;
1695 cout << "sample: " << sample1 << " -> ";
1696 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1698 for (int i = 0; i < 108003; i++) {
1699 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1700 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1702 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1703 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1704 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1705 cout << "sample: " << sample1 << endl;
1706 cout << "sample: " << sample1 << " -> ";
1707 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1711 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1712 cout << "ERROR: timecode2 not equal timecode1" << endl;
1713 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1714 cout << "sample: " << sample1 << endl;
1715 cout << "sample: " << sample1 << " -> ";
1716 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1719 oldsample = sample1;
1720 _session->timecode_decrement( timecode1 );
1723 cout << "sample_decrement: " << sample_increment << endl;
1724 cout << "sample: " << sample1 << " -> ";
1725 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1730 #ifdef Timecode_SAMPLE_TEST_5
1731 // Test 5: use_offset = true, use_subframes = false, increment seconds
1732 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1734 timecode1.hours = 0;
1735 timecode1.minutes = 0;
1736 timecode1.seconds = 0;
1737 timecode1.frames = 0;
1738 timecode1.subframes = 0;
1739 sample1 = oldsample = 0;
1740 sample_increment = _session->frame_rate();
1742 _session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1743 cout << "Starting at sample: " << sample1 << " -> ";
1744 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1746 for (int i = 0; i < 3600; i++) {
1747 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1748 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1750 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1751 // cout << "sample: " << sample1 << endl;
1752 // cout << "sample: " << sample1 << " -> ";
1753 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1755 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1757 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1761 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1762 cout << "ERROR: timecode2 not equal timecode1" << endl;
1763 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1764 cout << "sample: " << sample1 << endl;
1765 cout << "sample: " << sample1 << " -> ";
1766 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1769 oldsample = sample1;
1770 _session->timecode_increment_seconds( timecode1 );
1773 cout << "sample_increment: " << sample_increment << endl;
1774 cout << "sample: " << sample1 << " -> ";
1775 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1779 #ifdef Timecode_SAMPLE_TEST_6
1780 // Test 6: use_offset = true, use_subframes = false, increment minutes
1781 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1783 timecode1.hours = 0;
1784 timecode1.minutes = 0;
1785 timecode1.seconds = 0;
1786 timecode1.frames = 0;
1787 timecode1.subframes = 0;
1788 sample1 = oldsample = 0;
1789 sample_increment = _session->frame_rate() * 60;
1791 _session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1792 cout << "Starting at sample: " << sample1 << " -> ";
1793 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1795 for (int i = 0; i < 60; i++) {
1796 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1797 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1799 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1800 // cout << "sample: " << sample1 << endl;
1801 // cout << "sample: " << sample1 << " -> ";
1802 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1804 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1806 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1810 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1811 cout << "ERROR: timecode2 not equal timecode1" << endl;
1812 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1813 cout << "sample: " << sample1 << endl;
1814 cout << "sample: " << sample1 << " -> ";
1815 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1818 oldsample = sample1;
1819 _session->timecode_increment_minutes( timecode1 );
1822 cout << "sample_increment: " << sample_increment << endl;
1823 cout << "sample: " << sample1 << " -> ";
1824 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1827 #ifdef Timecode_SAMPLE_TEST_7
1828 // Test 7: use_offset = true, use_subframes = false, increment hours
1829 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1831 timecode1.hours = 0;
1832 timecode1.minutes = 0;
1833 timecode1.seconds = 0;
1834 timecode1.frames = 0;
1835 timecode1.subframes = 0;
1836 sample1 = oldsample = 0;
1837 sample_increment = _session->frame_rate() * 60 * 60;
1839 _session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1840 cout << "Starting at sample: " << sample1 << " -> ";
1841 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1843 for (int i = 0; i < 10; i++) {
1844 _session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1845 _session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1847 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1848 // cout << "sample: " << sample1 << endl;
1849 // cout << "sample: " << sample1 << " -> ";
1850 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1852 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1854 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1858 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1859 cout << "ERROR: timecode2 not equal timecode1" << endl;
1860 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1861 cout << "sample: " << sample1 << endl;
1862 cout << "sample: " << sample1 << " -> ";
1863 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1866 oldsample = sample1;
1867 _session->timecode_increment_hours( timecode1 );
1870 cout << "sample_increment: " << sample_increment << endl;
1871 cout << "sample: " << sample1 << " -> ";
1872 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1881 AudioClock::minsec_frame_from_display () const
1883 if (_session == 0) {
1887 int hrs = atoi (ms_hours_label.get_text());
1888 int mins = atoi (ms_minutes_label.get_text());
1889 float secs = atof (ms_seconds_label.get_text());
1891 nframes_t sr = _session->frame_rate();
1893 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1897 AudioClock::bbt_frame_from_display (nframes_t pos) const
1899 if (_session == 0) {
1900 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1905 any.type = AnyTime::BBT;
1907 any.bbt.bars = atoi (bars_label.get_text());
1908 any.bbt.beats = atoi (beats_label.get_text());
1909 any.bbt.ticks = atoi (ticks_label.get_text());
1916 nframes_t ret = _session->convert_to_frames_at (pos, any);
1923 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1925 if (_session == 0) {
1926 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1933 bbt.bars = atoi (bars_label.get_text());
1934 bbt.beats = atoi (beats_label.get_text());
1935 bbt.ticks = atoi (ticks_label.get_text());
1937 return _session->tempo_map().bbt_duration_at(pos,bbt,1);
1941 AudioClock::audio_frame_from_display () const
1943 return (nframes_t) atoi (audio_frames_label.get_text());
1947 AudioClock::build_ops_menu ()
1949 using namespace Menu_Helpers;
1950 ops_menu = new Menu;
1951 MenuList& ops_items = ops_menu->items();
1952 ops_menu->set_name ("ArdourContextMenu");
1954 if (!Profile->get_sae()) {
1955 ops_items.push_back (MenuElem (_("Timecode"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Timecode)));
1957 ops_items.push_back (MenuElem (_("Bars:Beats"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), BBT)));
1958 ops_items.push_back (MenuElem (_("Minutes:Seconds"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), MinSec)));
1959 ops_items.push_back (MenuElem (_("Samples"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Frames)));
1960 ops_items.push_back (MenuElem (_("Off"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Off)));
1962 if (editable && !is_duration && !_follows_playhead) {
1963 ops_items.push_back (SeparatorElem());
1964 ops_items.push_back (MenuElem (_("Set From Playhead"), sigc::mem_fun(*this, &AudioClock::set_from_playhead)));
1965 ops_items.push_back (MenuElem (_("Locate to this time"), sigc::mem_fun(*this, &AudioClock::locate)));
1970 AudioClock::set_from_playhead ()
1976 set (_session->transport_frame());
1980 AudioClock::locate ()
1982 if (!_session || is_duration) {
1986 _session->request_locate (current_time(), false);
1990 AudioClock::set_mode (Mode m)
1992 /* slightly tricky: this is called from within the ARDOUR_UI
1993 constructor by some of its clock members. at that time
1994 the instance pointer is unset, so we have to be careful.
1995 the main idea is to drop keyboard focus in case we had
1996 started editing the clock and then we switch clock mode.
1999 clock_base.grab_focus ();
2005 clock_base.remove ();
2011 clock_base.add (timecode_packer_hbox);
2015 clock_base.add (bbt_packer_hbox);
2019 clock_base.add (minsec_packer_hbox);
2023 clock_base.add (frames_packer_hbox);
2027 clock_base.add (off_hbox);
2031 set_size_requests ();
2033 set (last_when, true);
2034 clock_base.show_all ();
2035 key_entry_state = 0;
2037 if (!is_transient) {
2038 ModeChanged (); /* EMIT SIGNAL */
2039 mode_changed (); /* EMIT SIGNAL */
2044 AudioClock::set_size_requests ()
2046 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
2050 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
2051 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
2052 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
2053 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
2057 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
2058 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
2059 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
2063 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
2064 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
2065 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
2069 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
2073 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);
2080 AudioClock::set_bbt_reference (nframes64_t pos)
2082 bbt_reference_time = pos;