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;
46 using Gtkmm2ext::Keyboard;
51 sigc::signal<void> AudioClock::ModeChanged;
52 vector<AudioClock*> AudioClock::clocks;
54 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
55 2, /* Timecode_Hours */
56 2, /* Timecode_Minutes */
57 2, /* Timecode_Seconds */
58 2, /* Timecode_Frames */
68 AudioClock::AudioClock (
69 std::string clock_name, bool transient, std::string widget_name, bool allow_edit, bool follows_playhead, bool duration, bool with_info
72 is_transient (transient),
73 is_duration (duration),
74 editable (allow_edit),
75 _follows_playhead (follows_playhead),
92 bbt_reference_time = -1;
95 frames_upper_info_label = manage (new Label);
96 frames_lower_info_label = manage (new Label);
97 timecode_upper_info_label = manage (new Label);
98 timecode_lower_info_label = manage (new Label);
99 bbt_upper_info_label = manage (new Label);
100 bbt_lower_info_label = manage (new Label);
102 frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
103 frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
104 timecode_upper_info_label->set_name ("AudioClockTimecodeUpperInfo");
105 timecode_lower_info_label->set_name ("AudioClockTimecodeLowerInfo");
106 bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
107 bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
109 Gtkmm2ext::set_size_request_to_display_given_text(*timecode_upper_info_label, "23.98",0,0);
110 Gtkmm2ext::set_size_request_to_display_given_text(*timecode_lower_info_label, "NDF",0,0);
112 Gtkmm2ext::set_size_request_to_display_given_text(*bbt_upper_info_label, "88|88",0,0);
113 Gtkmm2ext::set_size_request_to_display_given_text(*bbt_lower_info_label, "888.88",0,0);
115 frames_info_box.pack_start (*frames_upper_info_label, true, true);
116 frames_info_box.pack_start (*frames_lower_info_label, true, true);
117 timecode_info_box.pack_start (*timecode_upper_info_label, true, true);
118 timecode_info_box.pack_start (*timecode_lower_info_label, true, true);
119 bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
120 bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
123 frames_upper_info_label = 0;
124 frames_lower_info_label = 0;
125 timecode_upper_info_label = 0;
126 timecode_lower_info_label = 0;
127 bbt_upper_info_label = 0;
128 bbt_lower_info_label = 0;
131 audio_frames_ebox.add (audio_frames_label);
133 frames_packer.set_homogeneous (false);
134 frames_packer.set_border_width (2);
135 frames_packer.pack_start (audio_frames_ebox, false, false);
138 frames_packer.pack_start (frames_info_box, false, false, 5);
141 frames_packer_hbox.pack_start (frames_packer, true, false);
143 hours_ebox.add (hours_label);
144 minutes_ebox.add (minutes_label);
145 seconds_ebox.add (seconds_label);
146 frames_ebox.add (frames_label);
147 bars_ebox.add (bars_label);
148 beats_ebox.add (beats_label);
149 ticks_ebox.add (ticks_label);
150 ms_hours_ebox.add (ms_hours_label);
151 ms_minutes_ebox.add (ms_minutes_label);
152 ms_seconds_ebox.add (ms_seconds_label);
154 timecode_packer.set_homogeneous (false);
155 timecode_packer.set_border_width (2);
156 timecode_packer.pack_start (hours_ebox, false, false);
157 timecode_packer.pack_start (colon1, false, false);
158 timecode_packer.pack_start (minutes_ebox, false, false);
159 timecode_packer.pack_start (colon2, false, false);
160 timecode_packer.pack_start (seconds_ebox, false, false);
161 timecode_packer.pack_start (colon3, false, false);
162 timecode_packer.pack_start (frames_ebox, false, false);
165 timecode_packer.pack_start (timecode_info_box, false, false, 5);
168 timecode_packer_hbox.pack_start (timecode_packer, true, false);
170 bbt_packer.set_homogeneous (false);
171 bbt_packer.set_border_width (2);
172 bbt_packer.pack_start (bars_ebox, false, false);
173 bbt_packer.pack_start (b1, false, false);
174 bbt_packer.pack_start (beats_ebox, false, false);
175 bbt_packer.pack_start (b2, false, false);
176 bbt_packer.pack_start (ticks_ebox, false, false);
179 bbt_packer.pack_start (bbt_info_box, false, false, 5);
182 bbt_packer_hbox.pack_start (bbt_packer, true, false);
184 minsec_packer.set_homogeneous (false);
185 minsec_packer.set_border_width (2);
186 minsec_packer.pack_start (ms_hours_ebox, false, false);
187 minsec_packer.pack_start (colon4, false, false);
188 minsec_packer.pack_start (ms_minutes_ebox, false, false);
189 minsec_packer.pack_start (colon5, false, false);
190 minsec_packer.pack_start (ms_seconds_ebox, false, false);
192 minsec_packer_hbox.pack_start (minsec_packer, true, false);
194 clock_frame.set_shadow_type (Gtk::SHADOW_IN);
195 clock_frame.set_name ("BaseFrame");
197 clock_frame.add (clock_base);
199 set_widget_name (widget_name);
201 _mode = BBT; /* lie to force mode switch */
204 pack_start (clock_frame, true, true);
206 /* the clock base handles button releases for menu popup regardless of
207 editable status. if the clock is editable, the clock base is where
208 we pass focus to after leaving the last editable "field", which
209 will then shutdown editing till the user starts it up again.
211 it does this because the focus out event on the field disables
212 keyboard event handling, and we don't connect anything up to
213 notice focus in on the clock base. hence, keyboard event handling
217 clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
218 clock_base.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &AudioClock::field_button_release_event), Timecode_Hours));
220 Session::TimecodeOffsetChanged.connect (sigc::mem_fun (*this, &AudioClock::timecode_offset_changed));
226 set (last_when, true);
229 clocks.push_back (this);
234 AudioClock::set_widget_name (string name)
236 Widget::set_name (name);
238 clock_base.set_name (name);
240 audio_frames_label.set_name (name);
241 hours_label.set_name (name);
242 minutes_label.set_name (name);
243 seconds_label.set_name (name);
244 frames_label.set_name (name);
245 bars_label.set_name (name);
246 beats_label.set_name (name);
247 ticks_label.set_name (name);
248 ms_hours_label.set_name (name);
249 ms_minutes_label.set_name (name);
250 ms_seconds_label.set_name (name);
251 hours_ebox.set_name (name);
252 minutes_ebox.set_name (name);
253 seconds_ebox.set_name (name);
254 frames_ebox.set_name (name);
255 audio_frames_ebox.set_name (name);
256 bars_ebox.set_name (name);
257 beats_ebox.set_name (name);
258 ticks_ebox.set_name (name);
259 ms_hours_ebox.set_name (name);
260 ms_minutes_ebox.set_name (name);
261 ms_seconds_ebox.set_name (name);
263 colon1.set_name (name);
264 colon2.set_name (name);
265 colon3.set_name (name);
266 colon4.set_name (name);
267 colon5.set_name (name);
275 AudioClock::setup_events ()
277 clock_base.set_flags (Gtk::CAN_FOCUS);
279 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);
280 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);
281 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);
282 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);
283 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);
284 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);
285 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);
286 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);
287 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);
288 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);
289 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);
291 hours_ebox.set_flags (Gtk::CAN_FOCUS);
292 minutes_ebox.set_flags (Gtk::CAN_FOCUS);
293 seconds_ebox.set_flags (Gtk::CAN_FOCUS);
294 frames_ebox.set_flags (Gtk::CAN_FOCUS);
295 audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
296 bars_ebox.set_flags (Gtk::CAN_FOCUS);
297 beats_ebox.set_flags (Gtk::CAN_FOCUS);
298 ticks_ebox.set_flags (Gtk::CAN_FOCUS);
299 ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
300 ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
301 ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
303 hours_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Hours));
304 minutes_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Minutes));
305 seconds_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Seconds));
306 frames_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Timecode_Frames));
307 audio_frames_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
308 bars_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
309 beats_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
310 ticks_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
311 ms_hours_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
312 ms_minutes_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
313 ms_seconds_ebox.signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
315 hours_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Hours));
316 minutes_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Minutes));
317 seconds_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Seconds));
318 frames_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Timecode_Frames));
319 audio_frames_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
320 bars_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Bars));
321 beats_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Beats));
322 ticks_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
323 ms_hours_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
324 ms_minutes_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
325 ms_seconds_ebox.signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
327 hours_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Hours));
328 minutes_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Minutes));
329 seconds_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Seconds));
330 frames_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Timecode_Frames));
331 audio_frames_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
332 bars_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Bars));
333 beats_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Beats));
334 ticks_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
335 ms_hours_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
336 ms_minutes_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
337 ms_seconds_ebox.signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
339 hours_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Hours));
340 minutes_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Minutes));
341 seconds_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Seconds));
342 frames_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Timecode_Frames));
343 audio_frames_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), AudioFrames));
344 bars_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Bars));
345 beats_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Beats));
346 ticks_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), Ticks));
347 ms_hours_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Hours));
348 ms_minutes_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes));
349 ms_seconds_ebox.signal_scroll_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds));
351 hours_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Hours));
352 minutes_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Minutes));
353 seconds_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Seconds));
354 frames_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Timecode_Frames));
355 audio_frames_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), AudioFrames));
356 bars_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Bars));
357 beats_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Beats));
358 ticks_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), Ticks));
359 ms_hours_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), MS_Hours));
360 ms_minutes_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), MS_Minutes));
361 ms_seconds_ebox.signal_key_press_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_press_event), MS_Seconds));
363 hours_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Hours));
364 minutes_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Minutes));
365 seconds_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Seconds));
366 frames_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Timecode_Frames));
367 audio_frames_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
368 bars_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Bars));
369 beats_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Beats));
370 ticks_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
371 ms_hours_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
372 ms_minutes_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
373 ms_seconds_ebox.signal_key_release_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
375 hours_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Hours));
376 minutes_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Minutes));
377 seconds_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Seconds));
378 frames_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Timecode_Frames));
379 audio_frames_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
380 bars_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
381 beats_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
382 ticks_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
383 ms_hours_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
384 ms_minutes_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
385 ms_seconds_ebox.signal_focus_in_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
387 hours_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Hours));
388 minutes_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Minutes));
389 seconds_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Seconds));
390 frames_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Timecode_Frames));
391 audio_frames_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
392 bars_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
393 beats_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
394 ticks_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
395 ms_hours_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
396 ms_minutes_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
397 ms_seconds_ebox.signal_focus_out_event().connect (sigc::bind (sigc::mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
399 clock_base.signal_focus_in_event().connect (sigc::mem_fun (*this, &AudioClock::drop_focus_handler));
403 AudioClock::drop_focus_handler (GdkEventFocus*)
405 Keyboard::magic_widget_drop_focus ();
410 AudioClock::on_realize ()
414 /* styles are not available until the widgets are bound to a window */
416 set_size_requests ();
420 AudioClock::set (nframes_t when, bool force, nframes_t offset, char which)
423 if ((!force && !is_visible()) || session == 0) {
427 if (when == last_when && !offset && !force) {
431 bool pdelta = Config->get_primary_clock_delta_edit_cursor();
432 bool sdelta = Config->get_secondary_clock_delta_edit_cursor();
434 if (offset && which == 'p' && pdelta) {
435 when = (when > offset) ? when - offset : offset - when;
436 } else if (offset && which == 's' && sdelta) {
437 when = (when > offset) ? when - offset : offset - when;
440 if (which == 'p' && pdelta && !last_pdelta) {
441 set_widget_name("TransportClockDisplayDelta");
443 } else if (which == 'p' && !pdelta && last_pdelta) {
444 set_widget_name("TransportClockDisplay");
446 } else if (which == 's' && sdelta && !last_sdelta) {
447 set_widget_name("SecondaryClockDisplayDelta");
449 } else if (which == 's' && !sdelta && last_sdelta) {
450 set_widget_name("SecondaryClockDisplay");
456 set_timecode (when, force);
460 set_bbt (when, force);
464 set_minsec (when, force);
468 set_frames (when, force);
479 AudioClock::timecode_offset_changed ()
486 current = current_duration();
488 current = current_time ();
498 AudioClock::set_frames (nframes_t when, bool /*force*/)
501 snprintf (buf, sizeof (buf), "%u", when);
502 audio_frames_label.set_text (buf);
504 if (frames_upper_info_label) {
505 nframes_t rate = session->frame_rate();
507 if (fmod (rate, 1000.0) == 0.000) {
508 sprintf (buf, "%uK", rate/1000);
510 sprintf (buf, "%.3fK", rate/1000.0f);
513 if (frames_upper_info_label->get_text() != buf) {
514 frames_upper_info_label->set_text (buf);
517 float vid_pullup = session->config.get_video_pullup();
519 if (vid_pullup == 0.0) {
520 if (frames_lower_info_label->get_text () != _("none")) {
521 frames_lower_info_label->set_text(_("none"));
524 sprintf (buf, "%-6.4f", vid_pullup);
525 if (frames_lower_info_label->get_text() != buf) {
526 frames_lower_info_label->set_text (buf);
533 AudioClock::set_minsec (nframes_t when, bool force)
542 hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
543 left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
544 mins = (int) floor (left / (session->frame_rate() * 60.0f));
545 left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
546 secs = left / (float) session->frame_rate();
548 if (force || hrs != ms_last_hrs) {
549 sprintf (buf, "%02d", hrs);
550 ms_hours_label.set_text (buf);
554 if (force || mins != ms_last_mins) {
555 sprintf (buf, "%02d", mins);
556 ms_minutes_label.set_text (buf);
560 if (force || secs != ms_last_secs) {
561 sprintf (buf, "%06.3f", secs);
562 ms_seconds_label.set_text (buf);
568 AudioClock::set_timecode (nframes_t when, bool force)
571 Timecode::Time timecode;
574 session->timecode_duration (when, timecode);
576 session->timecode_time (when, timecode);
579 if (force || timecode.hours != last_hrs || timecode.negative != last_negative) {
580 if (timecode.negative) {
581 sprintf (buf, "-%02" PRIu32, timecode.hours);
583 sprintf (buf, " %02" PRIu32, timecode.hours);
585 hours_label.set_text (buf);
586 last_hrs = timecode.hours;
587 last_negative = timecode.negative;
590 if (force || timecode.minutes != last_mins) {
591 sprintf (buf, "%02" PRIu32, timecode.minutes);
592 minutes_label.set_text (buf);
593 last_mins = timecode.minutes;
596 if (force || timecode.seconds != last_secs) {
597 sprintf (buf, "%02" PRIu32, timecode.seconds);
598 seconds_label.set_text (buf);
599 last_secs = timecode.seconds;
602 if (force || timecode.frames != last_frames) {
603 sprintf (buf, "%02" PRIu32, timecode.frames);
604 frames_label.set_text (buf);
605 last_frames = timecode.frames;
608 if (timecode_upper_info_label) {
609 double timecode_frames = session->timecode_frames_per_second();
611 if ( fmod(timecode_frames, 1.0) == 0.0) {
612 sprintf (buf, "%u", int (timecode_frames));
614 sprintf (buf, "%.2f", timecode_frames);
617 if (timecode_upper_info_label->get_text() != buf) {
618 timecode_upper_info_label->set_text (buf);
621 if ((fabs(timecode_frames - 29.97) < 0.0001) || timecode_frames == 30) {
622 if (session->timecode_drop_frames()) {
625 sprintf (buf, "NDF");
628 // there is no drop frame alternative
632 if (timecode_lower_info_label->get_text() != buf) {
633 timecode_lower_info_label->set_text (buf);
639 AudioClock::set_bbt (nframes_t when, bool force)
644 /* handle a common case */
651 session->tempo_map().bbt_time (when, bbt);
656 session->tempo_map().bbt_time (when, bbt);
659 sprintf (buf, "%03" PRIu32, bbt.bars);
660 if (force || bars_label.get_text () != buf) {
661 bars_label.set_text (buf);
663 sprintf (buf, "%02" PRIu32, bbt.beats);
664 if (force || beats_label.get_text () != buf) {
665 beats_label.set_text (buf);
667 sprintf (buf, "%04" PRIu32, bbt.ticks);
668 if (force || ticks_label.get_text () != buf) {
669 ticks_label.set_text (buf);
672 if (bbt_upper_info_label) {
675 if (bbt_reference_time < 0) {
678 pos = bbt_reference_time;
681 TempoMetric m (session->tempo_map().metric_at (pos));
683 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
684 if (bbt_lower_info_label->get_text() != buf) {
685 bbt_lower_info_label->set_text (buf);
687 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
688 if (bbt_upper_info_label->get_text() != buf) {
689 bbt_upper_info_label->set_text (buf);
695 AudioClock::set_session (Session *s)
702 XMLNode* node = session->extra_xml (X_("ClockModes"));
703 AudioClock::Mode amode;
706 if ((prop = node->property (_name)) != 0) {
707 amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
712 set (last_when, true);
721 hours_ebox.grab_focus ();
725 bars_ebox.grab_focus ();
729 ms_hours_ebox.grab_focus ();
733 frames_ebox.grab_focus ();
743 AudioClock::field_key_press_event (GdkEventKey */*ev*/, Field /*field*/)
745 /* all key activity is handled on key release */
750 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
755 bool move_on = false;
759 label = &hours_label;
761 case Timecode_Minutes:
762 label = &minutes_label;
764 case Timecode_Seconds:
765 label = &seconds_label;
767 case Timecode_Frames:
768 label = &frames_label;
772 label = &audio_frames_label;
776 label = &ms_hours_label;
779 label = &ms_minutes_label;
782 label = &ms_seconds_label;
789 label = &beats_label;
792 label = &ticks_label;
798 switch (ev->keyval) {
842 if (_mode == MinSec && field == MS_Seconds) {
857 clock_base.grab_focus ();
858 ChangeAborted(); /* EMIT SIGNAL */
867 if (key_entry_state == 0) {
869 /* initialize with a fresh new string */
871 if (field != AudioFrames) {
872 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
881 string existing = label->get_text();
882 if (existing.length() >= field_length[field]) {
883 new_text = existing.substr (1, field_length[field] - 1);
885 new_text = existing.substr (0, field_length[field] - 1);
889 new_text += new_char;
890 label->set_text (new_text);
894 if (key_entry_state == field_length[field]) {
900 if (key_entry_state) {
904 case Timecode_Minutes:
905 case Timecode_Seconds:
906 case Timecode_Frames:
907 // Check Timecode fields for sanity (may also adjust fields)
908 timecode_sanitize_display();
913 // Bars should never be, unless this clock is for a duration
914 if (atoi(bars_label.get_text()) == 0 && !is_duration) {
915 bars_label.set_text("001");
917 // beats should never be 0, unless this clock is for a duration
918 if (atoi(beats_label.get_text()) == 0 && !is_duration) {
919 beats_label.set_text("01");
926 ValueChanged(); /* EMIT_SIGNAL */
929 /* move on to the next field.
937 minutes_ebox.grab_focus ();
939 case Timecode_Minutes:
940 seconds_ebox.grab_focus ();
942 case Timecode_Seconds:
943 frames_ebox.grab_focus ();
945 case Timecode_Frames:
946 clock_base.grab_focus ();
951 clock_base.grab_focus ();
957 ms_minutes_ebox.grab_focus ();
960 ms_seconds_ebox.grab_focus ();
963 clock_base.grab_focus ();
969 beats_ebox.grab_focus ();
972 ticks_ebox.grab_focus ();
975 clock_base.grab_focus ();
984 //if user hit Enter, lose focus
985 switch (ev->keyval) {
988 clock_base.grab_focus ();
995 AudioClock::field_focus_in_event (GdkEventFocus */*ev*/, Field field)
999 Keyboard::magic_widget_grab_focus ();
1002 case Timecode_Hours:
1003 hours_ebox.set_flags (Gtk::HAS_FOCUS);
1004 hours_ebox.set_state (Gtk::STATE_ACTIVE);
1006 case Timecode_Minutes:
1007 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
1008 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
1010 case Timecode_Seconds:
1011 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
1012 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
1014 case Timecode_Frames:
1015 frames_ebox.set_flags (Gtk::HAS_FOCUS);
1016 frames_ebox.set_state (Gtk::STATE_ACTIVE);
1020 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
1021 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
1025 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
1026 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
1029 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
1030 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
1033 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
1034 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
1037 bars_ebox.set_flags (Gtk::HAS_FOCUS);
1038 bars_ebox.set_state (Gtk::STATE_ACTIVE);
1041 beats_ebox.set_flags (Gtk::HAS_FOCUS);
1042 beats_ebox.set_state (Gtk::STATE_ACTIVE);
1045 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
1046 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
1054 AudioClock::field_focus_out_event (GdkEventFocus */*ev*/, Field field)
1058 case Timecode_Hours:
1059 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1060 hours_ebox.set_state (Gtk::STATE_NORMAL);
1062 case Timecode_Minutes:
1063 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1064 minutes_ebox.set_state (Gtk::STATE_NORMAL);
1066 case Timecode_Seconds:
1067 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1068 seconds_ebox.set_state (Gtk::STATE_NORMAL);
1070 case Timecode_Frames:
1071 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1072 frames_ebox.set_state (Gtk::STATE_NORMAL);
1076 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
1077 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
1081 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
1082 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
1085 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
1086 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
1089 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
1090 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
1094 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
1095 bars_ebox.set_state (Gtk::STATE_NORMAL);
1098 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
1099 beats_ebox.set_state (Gtk::STATE_NORMAL);
1102 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
1103 ticks_ebox.set_state (Gtk::STATE_NORMAL);
1107 Keyboard::magic_widget_drop_focus ();
1113 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
1116 cerr << "button event on clock but we are dragging\n";
1117 gdk_pointer_ungrab (GDK_CURRENT_TIME);
1119 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
1120 // we actually dragged so return without setting editing focus, or we shift clicked
1126 if (ops_menu == 0) {
1129 ops_menu->popup (1, ev->time);
1133 if (Keyboard::is_context_menu_event (ev)) {
1134 cerr << "Context menu event on clock\n";
1135 if (ops_menu == 0) {
1138 ops_menu->popup (1, ev->time);
1142 switch (ev->button) {
1145 case Timecode_Hours:
1146 hours_ebox.grab_focus();
1148 case Timecode_Minutes:
1149 minutes_ebox.grab_focus();
1151 case Timecode_Seconds:
1152 seconds_ebox.grab_focus();
1154 case Timecode_Frames:
1155 frames_ebox.grab_focus();
1159 audio_frames_ebox.grab_focus();
1163 ms_hours_ebox.grab_focus();
1166 ms_minutes_ebox.grab_focus();
1169 ms_seconds_ebox.grab_focus();
1173 bars_ebox.grab_focus ();
1176 beats_ebox.grab_focus ();
1179 ticks_ebox.grab_focus ();
1192 AudioClock::field_button_press_event (GdkEventButton *ev, Field /*field*/)
1198 nframes_t frames = 0;
1200 switch (ev->button) {
1202 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1204 ValueChanged (); /* EMIT_SIGNAL */
1207 /* make absolutely sure that the pointer is grabbed */
1208 gdk_pointer_grab(ev->window,false ,
1209 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
1210 NULL,NULL,ev->time);
1213 drag_start_y = ev->y;
1218 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
1220 ValueChanged (); /* EMIT_SIGNAL */
1225 /* used for context sensitive menu */
1238 AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field)
1244 nframes_t frames = 0;
1246 switch (ev->direction) {
1249 frames = get_frames (field);
1251 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1254 set (current_time() + frames, true);
1255 ValueChanged (); /* EMIT_SIGNAL */
1259 case GDK_SCROLL_DOWN:
1260 frames = get_frames (field);
1262 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1266 if ((double)current_time() - (double)frames < 0.0) {
1269 set (current_time() - frames, true);
1272 ValueChanged (); /* EMIT_SIGNAL */
1285 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
1287 if (session == 0 || !dragging) {
1291 float pixel_frame_scale_factor = 0.2f;
1294 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1295 pixel_frame_scale_factor = 0.1f;
1299 if (Keyboard::modifier_state_contains (ev->state,
1300 Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) {
1302 pixel_frame_scale_factor = 0.025f;
1305 double y_delta = ev->y - drag_y;
1307 drag_accum += y_delta*pixel_frame_scale_factor;
1311 if (trunc(drag_accum) != 0) {
1316 dir = (drag_accum < 0 ? 1:-1);
1317 pos = current_time();
1318 frames = get_frames (field,pos,dir);
1320 if (frames != 0 && frames * drag_accum < current_time()) {
1322 set ((nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1330 ValueChanged(); /* EMIT_SIGNAL */
1339 AudioClock::get_frames (Field field,nframes_t pos,int dir)
1342 nframes_t frames = 0;
1345 case Timecode_Hours:
1346 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1348 case Timecode_Minutes:
1349 frames = (nframes_t) floor (60.0 * session->frame_rate());
1351 case Timecode_Seconds:
1352 frames = session->frame_rate();
1354 case Timecode_Frames:
1355 frames = (nframes_t) floor (session->frame_rate() / session->timecode_frames_per_second());
1363 frames = (nframes_t) floor (3600.0 * session->frame_rate());
1366 frames = (nframes_t) floor (60.0 * session->frame_rate());
1369 frames = session->frame_rate();
1376 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1382 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1388 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1396 AudioClock::current_time (nframes_t pos) const
1402 ret = timecode_frame_from_display ();
1405 ret = bbt_frame_from_display (pos);
1409 ret = minsec_frame_from_display ();
1413 ret = audio_frame_from_display ();
1424 AudioClock::current_duration (nframes_t pos) const
1430 ret = timecode_frame_from_display ();
1433 ret = bbt_frame_duration_from_display (pos);
1437 ret = minsec_frame_from_display ();
1441 ret = audio_frame_from_display ();
1452 AudioClock::timecode_sanitize_display()
1454 // Check Timecode fields for sanity, possibly adjusting values
1455 if (atoi(minutes_label.get_text()) > 59) {
1456 minutes_label.set_text("59");
1459 if (atoi(seconds_label.get_text()) > 59) {
1460 seconds_label.set_text("59");
1463 switch ((long)rint(session->timecode_frames_per_second())) {
1465 if (atoi(frames_label.get_text()) > 23) {
1466 frames_label.set_text("23");
1470 if (atoi(frames_label.get_text()) > 24) {
1471 frames_label.set_text("24");
1475 if (atoi(frames_label.get_text()) > 29) {
1476 frames_label.set_text("29");
1483 if (session->timecode_drop_frames()) {
1484 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1485 frames_label.set_text("02");
1491 AudioClock::timecode_frame_from_display () const
1497 Timecode::Time timecode;
1500 timecode.hours = atoi (hours_label.get_text());
1501 timecode.minutes = atoi (minutes_label.get_text());
1502 timecode.seconds = atoi (seconds_label.get_text());
1503 timecode.frames = atoi (frames_label.get_text());
1504 timecode.rate = session->timecode_frames_per_second();
1505 timecode.drop= session->timecode_drop_frames();
1507 session->timecode_to_sample( timecode, sample, false /* use_offset */, false /* use_subframes */ );
1511 #define Timecode_SAMPLE_TEST_1
1512 #define Timecode_SAMPLE_TEST_2
1513 #define Timecode_SAMPLE_TEST_3
1514 #define Timecode_SAMPLE_TEST_4
1515 #define Timecode_SAMPLE_TEST_5
1516 #define Timecode_SAMPLE_TEST_6
1517 #define Timecode_SAMPLE_TEST_7
1519 // Testcode for timecode<->sample conversions (P.S.)
1520 Timecode::Time timecode1;
1522 nframes_t oldsample = 0;
1523 Timecode::Time timecode2;
1524 nframes_t sample_increment;
1526 sample_increment = (long)rint(session->frame_rate() / session->timecode_frames_per_second);
1528 #ifdef Timecode_SAMPLE_TEST_1
1529 // Test 1: use_offset = false, use_subframes = false
1530 cout << "use_offset = false, use_subframes = false" << endl;
1531 for (int i = 0; i < 108003; i++) {
1532 session->timecode_to_sample( timecode1, sample1, false /* use_offset */, false /* use_subframes */ );
1533 session->sample_to_timecode( sample1, timecode2, false /* use_offset */, false /* use_subframes */ );
1535 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1536 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1537 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1538 cout << "sample: " << sample1 << endl;
1539 cout << "sample: " << sample1 << " -> ";
1540 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1544 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1545 cout << "ERROR: timecode2 not equal timecode1" << endl;
1546 cout << "timecode1: " << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1547 cout << "sample: " << sample1 << endl;
1548 cout << "sample: " << sample1 << " -> ";
1549 cout << "timecode2: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1552 oldsample = sample1;
1553 session->timecode_increment( timecode1 );
1556 cout << "sample_increment: " << sample_increment << endl;
1557 cout << "sample: " << sample1 << " -> ";
1558 cout << "timecode: " << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1561 #ifdef Timecode_SAMPLE_TEST_2
1562 // Test 2: use_offset = true, use_subframes = false
1563 cout << "use_offset = true, use_subframes = false" << endl;
1565 timecode1.hours = 0;
1566 timecode1.minutes = 0;
1567 timecode1.seconds = 0;
1568 timecode1.frames = 0;
1569 timecode1.subframes = 0;
1570 sample1 = oldsample = 0;
1572 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1573 cout << "Starting at sample: " << sample1 << " -> ";
1574 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1576 for (int i = 0; i < 108003; i++) {
1577 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1578 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1580 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1581 // cout << "sample: " << sample1 << endl;
1582 // cout << "sample: " << sample1 << " -> ";
1583 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1585 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1586 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1587 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1588 cout << "sample: " << sample1 << endl;
1589 cout << "sample: " << sample1 << " -> ";
1590 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1594 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1595 cout << "ERROR: timecode2 not equal timecode1" << endl;
1596 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1597 cout << "sample: " << sample1 << endl;
1598 cout << "sample: " << sample1 << " -> ";
1599 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1602 oldsample = sample1;
1603 session->timecode_increment( timecode1 );
1606 cout << "sample_increment: " << sample_increment << endl;
1607 cout << "sample: " << sample1 << " -> ";
1608 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1611 #ifdef Timecode_SAMPLE_TEST_3
1612 // Test 3: use_offset = true, use_subframes = false, decrement
1613 cout << "use_offset = true, use_subframes = false, decrement" << endl;
1615 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1616 cout << "Starting at sample: " << sample1 << " -> ";
1617 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1619 for (int i = 0; i < 108003; i++) {
1620 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1621 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1623 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1624 // cout << "sample: " << sample1 << endl;
1625 // cout << "sample: " << sample1 << " -> ";
1626 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1628 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1629 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1630 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1631 cout << "sample: " << sample1 << endl;
1632 cout << "sample: " << sample1 << " -> ";
1633 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1637 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1638 cout << "ERROR: timecode2 not equal timecode1" << endl;
1639 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1640 cout << "sample: " << sample1 << endl;
1641 cout << "sample: " << sample1 << " -> ";
1642 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1645 oldsample = sample1;
1646 session->timecode_decrement( timecode1 );
1649 cout << "sample_decrement: " << sample_increment << endl;
1650 cout << "sample: " << sample1 << " -> ";
1651 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1655 #ifdef Timecode_SAMPLE_TEST_4
1656 // Test 4: use_offset = true, use_subframes = true
1657 cout << "use_offset = true, use_subframes = true" << endl;
1659 for (long sub = 5; sub < 80; sub += 5) {
1660 timecode1.hours = 0;
1661 timecode1.minutes = 0;
1662 timecode1.seconds = 0;
1663 timecode1.frames = 0;
1664 timecode1.subframes = 0;
1665 sample1 = oldsample = (sample_increment * sub) / 80;
1667 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, true /* use_subframes */ );
1669 cout << "starting at sample: " << sample1 << " -> ";
1670 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1672 for (int i = 0; i < 108003; i++) {
1673 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1674 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1676 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1677 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1678 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1679 cout << "sample: " << sample1 << endl;
1680 cout << "sample: " << sample1 << " -> ";
1681 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1685 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1686 cout << "ERROR: timecode2 not equal timecode1" << endl;
1687 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1688 cout << "sample: " << sample1 << endl;
1689 cout << "sample: " << sample1 << " -> ";
1690 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1693 oldsample = sample1;
1694 session->timecode_increment( timecode1 );
1697 cout << "sample_increment: " << sample_increment << endl;
1698 cout << "sample: " << sample1 << " -> ";
1699 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1701 for (int i = 0; i < 108003; i++) {
1702 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, true /* use_subframes */ );
1703 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, true /* use_subframes */ );
1705 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1706 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1707 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1708 cout << "sample: " << sample1 << endl;
1709 cout << "sample: " << sample1 << " -> ";
1710 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1714 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames || timecode2.subframes != timecode1.subframes) {
1715 cout << "ERROR: timecode2 not equal timecode1" << endl;
1716 cout << "timecode1: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1717 cout << "sample: " << sample1 << endl;
1718 cout << "sample: " << sample1 << " -> ";
1719 cout << "timecode2: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1722 oldsample = sample1;
1723 session->timecode_decrement( timecode1 );
1726 cout << "sample_decrement: " << sample_increment << endl;
1727 cout << "sample: " << sample1 << " -> ";
1728 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1733 #ifdef Timecode_SAMPLE_TEST_5
1734 // Test 5: use_offset = true, use_subframes = false, increment seconds
1735 cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1737 timecode1.hours = 0;
1738 timecode1.minutes = 0;
1739 timecode1.seconds = 0;
1740 timecode1.frames = 0;
1741 timecode1.subframes = 0;
1742 sample1 = oldsample = 0;
1743 sample_increment = session->frame_rate();
1745 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1746 cout << "Starting at sample: " << sample1 << " -> ";
1747 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1749 for (int i = 0; i < 3600; i++) {
1750 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1751 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1753 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1754 // cout << "sample: " << sample1 << endl;
1755 // cout << "sample: " << sample1 << " -> ";
1756 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1758 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1760 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1764 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1765 cout << "ERROR: timecode2 not equal timecode1" << endl;
1766 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1767 cout << "sample: " << sample1 << endl;
1768 cout << "sample: " << sample1 << " -> ";
1769 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1772 oldsample = sample1;
1773 session->timecode_increment_seconds( timecode1 );
1776 cout << "sample_increment: " << sample_increment << endl;
1777 cout << "sample: " << sample1 << " -> ";
1778 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1782 #ifdef Timecode_SAMPLE_TEST_6
1783 // Test 6: use_offset = true, use_subframes = false, increment minutes
1784 cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1786 timecode1.hours = 0;
1787 timecode1.minutes = 0;
1788 timecode1.seconds = 0;
1789 timecode1.frames = 0;
1790 timecode1.subframes = 0;
1791 sample1 = oldsample = 0;
1792 sample_increment = session->frame_rate() * 60;
1794 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1795 cout << "Starting at sample: " << sample1 << " -> ";
1796 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1798 for (int i = 0; i < 60; i++) {
1799 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1800 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1802 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1803 // cout << "sample: " << sample1 << endl;
1804 // cout << "sample: " << sample1 << " -> ";
1805 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1807 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1809 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1813 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1814 cout << "ERROR: timecode2 not equal timecode1" << endl;
1815 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1816 cout << "sample: " << sample1 << endl;
1817 cout << "sample: " << sample1 << " -> ";
1818 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1821 oldsample = sample1;
1822 session->timecode_increment_minutes( timecode1 );
1825 cout << "sample_increment: " << sample_increment << endl;
1826 cout << "sample: " << sample1 << " -> ";
1827 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1830 #ifdef Timecode_SAMPLE_TEST_7
1831 // Test 7: use_offset = true, use_subframes = false, increment hours
1832 cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1834 timecode1.hours = 0;
1835 timecode1.minutes = 0;
1836 timecode1.seconds = 0;
1837 timecode1.frames = 0;
1838 timecode1.subframes = 0;
1839 sample1 = oldsample = 0;
1840 sample_increment = session->frame_rate() * 60 * 60;
1842 session->sample_to_timecode( sample1, timecode1, true /* use_offset */, false /* use_subframes */ );
1843 cout << "Starting at sample: " << sample1 << " -> ";
1844 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << endl;
1846 for (int i = 0; i < 10; i++) {
1847 session->timecode_to_sample( timecode1, sample1, true /* use_offset */, false /* use_subframes */ );
1848 session->sample_to_timecode( sample1, timecode2, true /* use_offset */, false /* use_subframes */ );
1850 // cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1851 // cout << "sample: " << sample1 << endl;
1852 // cout << "sample: " << sample1 << " -> ";
1853 // cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1855 // if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1857 // cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1861 if (timecode2.hours != timecode1.hours || timecode2.minutes != timecode1.minutes || timecode2.seconds != timecode2.seconds || timecode2.frames != timecode1.frames) {
1862 cout << "ERROR: timecode2 not equal timecode1" << endl;
1863 cout << "timecode: " << (timecode1.negative ? "-" : "") << timecode1.hours << ":" << timecode1.minutes << ":" << timecode1.seconds << ":" << timecode1.frames << "::" << timecode1.subframes << " -> ";
1864 cout << "sample: " << sample1 << endl;
1865 cout << "sample: " << sample1 << " -> ";
1866 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1869 oldsample = sample1;
1870 session->timecode_increment_hours( timecode1 );
1873 cout << "sample_increment: " << sample_increment << endl;
1874 cout << "sample: " << sample1 << " -> ";
1875 cout << "timecode: " << (timecode2.negative ? "-" : "") << timecode2.hours << ":" << timecode2.minutes << ":" << timecode2.seconds << ":" << timecode2.frames << "::" << timecode2.subframes << endl;
1884 AudioClock::minsec_frame_from_display () const
1890 int hrs = atoi (ms_hours_label.get_text());
1891 int mins = atoi (ms_minutes_label.get_text());
1892 float secs = atof (ms_seconds_label.get_text());
1894 nframes_t sr = session->frame_rate();
1896 return (nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1900 AudioClock::bbt_frame_from_display (nframes_t pos) const
1903 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1908 any.type = AnyTime::BBT;
1910 any.bbt.bars = atoi (bars_label.get_text());
1911 any.bbt.beats = atoi (beats_label.get_text());
1912 any.bbt.ticks = atoi (ticks_label.get_text());
1919 nframes_t ret = session->convert_to_frames_at (pos, any);
1926 AudioClock::bbt_frame_duration_from_display (nframes_t pos) const
1929 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1936 bbt.bars = atoi (bars_label.get_text());
1937 bbt.beats = atoi (beats_label.get_text());
1938 bbt.ticks = atoi (ticks_label.get_text());
1940 return session->tempo_map().bbt_duration_at(pos,bbt,1);
1944 AudioClock::audio_frame_from_display () const
1946 return (nframes_t) atoi (audio_frames_label.get_text());
1950 AudioClock::build_ops_menu ()
1952 using namespace Menu_Helpers;
1953 ops_menu = new Menu;
1954 MenuList& ops_items = ops_menu->items();
1955 ops_menu->set_name ("ArdourContextMenu");
1957 if (!Profile->get_sae()) {
1958 ops_items.push_back (MenuElem (_("Timecode"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Timecode)));
1960 ops_items.push_back (MenuElem (_("Bars:Beats"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), BBT)));
1961 ops_items.push_back (MenuElem (_("Minutes:Seconds"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), MinSec)));
1962 ops_items.push_back (MenuElem (_("Samples"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Frames)));
1963 ops_items.push_back (MenuElem (_("Off"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Off)));
1965 if (editable && !is_duration && !_follows_playhead) {
1966 ops_items.push_back (SeparatorElem());
1967 ops_items.push_back (MenuElem (_("Set From Playhead"), sigc::mem_fun(*this, &AudioClock::set_from_playhead)));
1968 ops_items.push_back (MenuElem (_("Locate to this time"), sigc::mem_fun(*this, &AudioClock::locate)));
1973 AudioClock::set_from_playhead ()
1979 set (session->transport_frame());
1983 AudioClock::locate ()
1985 if (!session || is_duration) {
1989 session->request_locate (current_time(), false);
1993 AudioClock::set_mode (Mode m)
1995 /* slightly tricky: this is called from within the ARDOUR_UI
1996 constructor by some of its clock members. at that time
1997 the instance pointer is unset, so we have to be careful.
1998 the main idea is to drop keyboard focus in case we had
1999 started editing the clock and then we switch clock mode.
2002 clock_base.grab_focus ();
2008 clock_base.remove ();
2014 clock_base.add (timecode_packer_hbox);
2018 clock_base.add (bbt_packer_hbox);
2022 clock_base.add (minsec_packer_hbox);
2026 clock_base.add (frames_packer_hbox);
2030 clock_base.add (off_hbox);
2034 set_size_requests ();
2036 set (last_when, true);
2037 clock_base.show_all ();
2038 key_entry_state = 0;
2040 if (!is_transient) {
2041 ModeChanged (); /* EMIT SIGNAL */
2042 mode_changed (); /* EMIT SIGNAL */
2047 AudioClock::set_size_requests ()
2049 /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
2053 Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
2054 Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
2055 Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
2056 Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
2060 Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
2061 Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
2062 Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
2066 Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
2067 Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
2068 Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
2072 Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
2076 Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5);
2083 AudioClock::set_bbt_reference (nframes64_t pos)
2085 bbt_reference_time = pos;