2 cleanup patches from nickm, plus work on mixer_ui.cc so that it compiles
[ardour.git] / gtk2_ardour / audio_clock.cc
1 /*
2     Copyright (C) 1999 Paul Davis 
3
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.
8
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.
13
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.
17
18     $Id$
19 */
20
21 #include <cstdio> // for sprintf
22 #include <cmath>
23 #include <gtkmm2ext/utils.h>
24
25 #include <ardour/ardour.h>
26 #include <ardour/session.h>
27 #include <ardour/tempo.h>
28 #include <sigc++/bind.h>
29
30 #include "ardour_ui.h"
31 #include "audio_clock.h"
32 #include "utils.h"
33 #include "keyboard.h"
34 #include "i18n.h"
35
36 using namespace ARDOUR;
37 using namespace sigc;
38 using namespace Gtk;
39
40 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
41         2,   /* SMPTE_Hours */
42         2,   /* SMPTE_Minutes */
43         2,   /* SMPTE_Seconds */
44         2,   /* SMPTE_Frames */
45         2,   /* MS_Hours */
46         2,   /* MS_Minutes */
47         5,   /* MS_Seconds */
48         3,   /* Bars */
49         2,   /* Beats */
50         4,   /* Tick */
51         10   /* Audio Frame */
52 };
53
54 AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool with_tempo_and_meter) 
55         : is_duration (duration),
56           editable (allow_edit),
57           colon1 (":"),
58           colon2 (":"),
59           colon3 (":"),
60           colon4 (":"),
61           colon5 (":"),
62           b1 ("|"),
63           b2 ("|")
64 {
65         session = 0;
66         last_when = 0;
67         key_entry_state = 0;
68         ops_menu = 0;
69         dragging = false;
70         
71         audio_frames_ebox.add (audio_frames_label);
72         frames_packer_hbox.set_border_width (2);
73         frames_packer_hbox.pack_start (audio_frames_ebox, false, false);
74
75         hours_ebox.add (hours_label);
76         minutes_ebox.add (minutes_label);
77         seconds_ebox.add (seconds_label);
78         frames_ebox.add (frames_label);
79         bars_ebox.add (bars_label);
80         beats_ebox.add (beats_label);
81         ticks_ebox.add (ticks_label);
82         ms_hours_ebox.add (ms_hours_label);
83         ms_minutes_ebox.add (ms_minutes_label);
84         ms_seconds_ebox.add (ms_seconds_label);
85
86         smpte_packer.set_homogeneous (false);
87         smpte_packer.set_border_width (2);
88         smpte_packer.pack_start (hours_ebox, false, false);
89         smpte_packer.pack_start (colon1, false, false);
90         smpte_packer.pack_start (minutes_ebox, false, false);
91         smpte_packer.pack_start (colon2, false, false);
92         smpte_packer.pack_start (seconds_ebox, false, false);
93         smpte_packer.pack_start (colon3, false, false);
94         smpte_packer.pack_start (frames_ebox, false, false);
95
96         smpte_packer_hbox.pack_start (smpte_packer, true, false);
97
98         bbt_packer.set_homogeneous (false);
99         bbt_packer.set_border_width (2);
100         bbt_packer.pack_start (bars_ebox, false, false);
101         bbt_packer.pack_start (b1, false, false);
102         bbt_packer.pack_start (beats_ebox, false, false);
103         bbt_packer.pack_start (b2, false, false);
104         bbt_packer.pack_start (ticks_ebox, false, false);
105
106         if (with_tempo_and_meter) {
107                 meter_label = manage (new Label);
108                 tempo_label = manage (new Label);
109
110                 meter_label->set_name ("BBTMeterLabel");
111                 tempo_label->set_name ("BBTTempoLabel");
112
113                 tempo_meter_box.pack_start (*meter_label, false, false);
114                 tempo_meter_box.pack_start (*tempo_label, false, false);
115
116                 bbt_packer.pack_start (tempo_meter_box, false, false, 5);
117         } else {
118                 meter_label = 0;
119                 tempo_label = 0;
120         }
121
122         bbt_packer_hbox.pack_start (bbt_packer, true, false);
123
124         minsec_packer.set_homogeneous (false);
125         minsec_packer.set_border_width (2);
126         minsec_packer.pack_start (ms_hours_ebox, false, false);
127         minsec_packer.pack_start (colon4, false, false);
128         minsec_packer.pack_start (ms_minutes_ebox, false, false);
129         minsec_packer.pack_start (colon5, false, false);
130         minsec_packer.pack_start (ms_seconds_ebox, false, false);
131
132         minsec_packer_hbox.pack_start (minsec_packer, true, false);
133
134         set_name (name);
135         clock_base.set_name (name);
136
137         audio_frames_label.set_name (name);
138         hours_label.set_name (name);
139         minutes_label.set_name (name);
140         seconds_label.set_name (name);
141         frames_label.set_name (name);
142         bars_label.set_name (name);
143         beats_label.set_name (name);
144         ticks_label.set_name (name);
145         ms_hours_label.set_name (name);
146         ms_minutes_label.set_name (name);
147         ms_seconds_label.set_name (name);
148         hours_ebox.set_name (name);
149         minutes_ebox.set_name (name);
150         seconds_ebox.set_name (name);
151         frames_ebox.set_name (name);
152         audio_frames_ebox.set_name (name);
153         bars_ebox.set_name (name);
154         beats_ebox.set_name (name);
155         ticks_ebox.set_name (name);
156         ms_hours_ebox.set_name (name);
157         ms_minutes_ebox.set_name (name);
158         ms_seconds_ebox.set_name (name);
159         
160         colon1.set_name (name);
161         colon2.set_name (name);
162         colon3.set_name (name);
163         colon4.set_name (name);
164         colon5.set_name (name);
165         b1.set_name (name);
166         b2.set_name (name);
167
168         clock_frame.set_shadow_type (Gtk::SHADOW_IN);
169         clock_frame.set_name ("BaseFrame");
170
171         clock_frame.add (clock_base);
172
173         _mode = BBT; /* lie to force mode switch */
174         set_mode (SMPTE);
175
176         pack_start (clock_frame, true, true);
177
178         /* the clock base handles button releases for menu popup regardless of
179            editable status. if the clock is editable, the clock base is where
180            we pass focus to after leaving the last editable "field", which
181            will then shutdown editing till the user starts it up again.
182
183            it does this because the focus out event on the field disables
184            keyboard event handling, and we don't connect anything up to
185            notice focus in on the clock base. hence, keyboard event handling
186            stays disabled.
187         */
188
189         clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
190         clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
191
192         if (editable) {
193                 setup_events ();
194         }
195
196         set (last_when, true);
197 }
198
199 void
200 AudioClock::setup_events ()
201 {
202         clock_base.set_flags (Gtk::CAN_FOCUS);
203
204         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);
205         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);
206         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);
207         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);
208         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);
209         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);
210         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);
211         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);
212         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);
213         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);
214         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);
215
216         hours_ebox.set_flags (Gtk::CAN_FOCUS);
217         minutes_ebox.set_flags (Gtk::CAN_FOCUS);
218         seconds_ebox.set_flags (Gtk::CAN_FOCUS);
219         frames_ebox.set_flags (Gtk::CAN_FOCUS);
220         audio_frames_ebox.set_flags (Gtk::CAN_FOCUS);
221         bars_ebox.set_flags (Gtk::CAN_FOCUS);
222         beats_ebox.set_flags (Gtk::CAN_FOCUS);
223         ticks_ebox.set_flags (Gtk::CAN_FOCUS);
224         ms_hours_ebox.set_flags (Gtk::CAN_FOCUS);
225         ms_minutes_ebox.set_flags (Gtk::CAN_FOCUS);
226         ms_seconds_ebox.set_flags (Gtk::CAN_FOCUS);
227
228         hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Hours));
229         minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Minutes));
230         seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Seconds));
231         frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), SMPTE_Frames));
232         audio_frames_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), AudioFrames));
233         bars_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Bars));
234         beats_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Beats));
235         ticks_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), Ticks));
236         ms_hours_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Hours));
237         ms_minutes_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Minutes));
238         ms_seconds_ebox.signal_motion_notify_event().connect (bind (mem_fun(*this, &AudioClock::field_motion_notify_event), MS_Seconds));
239
240         hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Hours));
241         minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Minutes));
242         seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Seconds));
243         frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), SMPTE_Frames));
244         audio_frames_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), AudioFrames));
245         bars_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Bars));
246         beats_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Beats));
247         ticks_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), Ticks));
248         ms_hours_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Hours));
249         ms_minutes_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Minutes));
250         ms_seconds_ebox.signal_button_press_event().connect (bind (mem_fun(*this, &AudioClock::field_button_press_event), MS_Seconds));
251
252         hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Hours));
253         minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Minutes));
254         seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Seconds));
255         frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), SMPTE_Frames));
256         audio_frames_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), AudioFrames));
257         bars_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Bars));
258         beats_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Beats));
259         ticks_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), Ticks));
260         ms_hours_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Hours));
261         ms_minutes_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Minutes));
262         ms_seconds_ebox.signal_button_release_event().connect (bind (mem_fun(*this, &AudioClock::field_button_release_event), MS_Seconds));
263
264         hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours));
265         minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes));
266         seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds));
267         frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Frames));
268         audio_frames_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), AudioFrames));
269         bars_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Bars));
270         beats_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Beats));
271         ticks_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), Ticks));
272         ms_hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Hours));
273         ms_minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Minutes));
274         ms_seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), MS_Seconds));
275
276         hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Hours));
277         minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Minutes));
278         seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Seconds));
279         frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), SMPTE_Frames));
280         audio_frames_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), AudioFrames));
281         bars_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Bars));
282         beats_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Beats));
283         ticks_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), Ticks));
284         ms_hours_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Hours));
285         ms_minutes_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Minutes));
286         ms_seconds_ebox.signal_focus_in_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_in_event), MS_Seconds));
287
288         hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Hours));
289         minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Minutes));
290         seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Seconds));
291         frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), SMPTE_Frames));
292         audio_frames_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), AudioFrames));
293         bars_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Bars));
294         beats_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Beats));
295         ticks_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), Ticks));
296         ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours));
297         ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes));
298         ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds));
299
300         Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 0, 2);
301         Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 0, 2);
302         Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 0, 2);
303         Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 0, 2);
304
305         Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 0, 2);
306         Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 0, 2);
307         Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 0, 2);
308
309         Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 0, 2);
310 }
311
312 void
313 AudioClock::on_realize ()
314 {
315         HBox::on_realize ();
316 }
317
318 void
319 AudioClock::set (jack_nframes_t when, bool force)
320 {
321
322         if ((!force && !is_visible()) || session == 0) {
323                 return;
324         }
325         
326         if (when == last_when && !force) {
327                 return;
328         }
329
330         switch (_mode) {
331         case SMPTE:
332                 set_smpte (when, force);
333                 break;
334
335         case BBT:
336                 set_bbt (when, force);
337                 break;
338
339         case MinSec:
340                 set_minsec (when, force);
341                 break;
342
343         case Frames:
344                 set_frames (when, force);
345                 break;
346
347         case Off:
348                 break;
349         }
350
351         last_when = when;
352 }
353
354 void
355 AudioClock::set_frames (jack_nframes_t when, bool force)
356 {
357         char buf[32];
358         snprintf (buf, sizeof (buf), "%u", when);
359         audio_frames_label.set_text (buf);
360 }       
361
362 void
363 AudioClock::set_minsec (jack_nframes_t when, bool force)
364 {
365         char buf[32];
366         jack_nframes_t left;
367         int hrs;
368         int mins;
369         float secs;
370         
371         left = when;
372         hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
373         left -= (jack_nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
374         mins = (int) floor (left / (session->frame_rate() * 60.0f));
375         left -= (jack_nframes_t) floor (mins * session->frame_rate() * 60.0f);
376         secs = left / (float) session->frame_rate();
377
378         if (force || hrs != ms_last_hrs) {
379                 sprintf (buf, "%d", hrs);
380                 ms_hours_label.set_text (buf);
381                 ms_last_hrs = hrs;
382         }
383
384         if (force || mins != ms_last_mins) {
385                 sprintf (buf, "%d", mins);
386                 ms_minutes_label.set_text (buf);
387                 ms_last_mins = mins;
388         }
389
390         if (force || secs != ms_last_secs) {
391                 sprintf (buf, "%06.3f", secs);
392                 ms_seconds_label.set_text (buf);
393                 ms_last_secs = secs;
394         }
395 }
396
397 void
398 AudioClock::set_smpte (jack_nframes_t when, bool force)
399 {
400         char buf[32];
401         SMPTE_Time smpte;
402         
403         if (is_duration) {
404                 session->smpte_duration (when, smpte);
405         } else {
406                 session->smpte_time (when, smpte);
407         }
408
409         if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
410                 if (smpte.negative) {
411                         sprintf (buf, "-%02ld", smpte.hours);
412                 } else {
413                         sprintf (buf, " %02ld", smpte.hours);
414                 }
415                 hours_label.set_text (buf);
416                 last_hrs = smpte.hours;
417                 last_negative = smpte.negative;
418         }
419
420         if (force || smpte.minutes != last_mins) {
421                 sprintf (buf, "%02ld", smpte.minutes);
422                 minutes_label.set_text (buf);
423                 last_mins = smpte.minutes;
424         }
425
426         if (force || smpte.seconds != last_secs) {
427                 sprintf (buf, "%02ld", smpte.seconds);
428                 seconds_label.set_text (buf);
429                 last_secs = smpte.seconds;
430         }
431
432         if (force || smpte.frames != last_frames) {
433                 sprintf (buf, "%02ld", smpte.frames);
434                 frames_label.set_text (buf);
435                 last_frames = smpte.frames;
436         }
437 }
438
439 void
440 AudioClock::set_bbt (jack_nframes_t when, bool force)
441 {
442         char buf[16];
443         BBT_Time bbt;
444
445         session->tempo_map().bbt_time (when, bbt);
446         sprintf (buf, "%03" PRIu32, bbt.bars);
447         bars_label.set_text (buf);
448         sprintf (buf, "%02" PRIu32, bbt.beats);
449         beats_label.set_text (buf);
450         sprintf (buf, "%04" PRIu32, bbt.ticks);
451         ticks_label.set_text (buf);
452         
453         if (meter_label) {
454                 TempoMap::Metric m (session->tempo_map().metric_at (when));
455                 sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
456                 tempo_label->set_text (buf);
457                 sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
458                 meter_label->set_text (buf);
459         }
460 }
461
462 void
463 AudioClock::set_session (Session *s)
464 {
465         session = s;
466
467         if (s) {
468                 set (last_when, true);
469         }
470 }
471
472 gint
473 AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
474 {
475         Label *label = 0;
476         string new_text;
477         char new_char = 0;
478         bool move_on = false;
479
480         switch (field) {
481         case SMPTE_Hours:
482                 label = &hours_label;
483                 break;
484         case SMPTE_Minutes:
485                 label = &minutes_label;
486                 break;
487         case SMPTE_Seconds:
488                 label = &seconds_label;
489                 break;
490         case SMPTE_Frames:
491                 label = &frames_label;
492                 break;
493
494         case AudioFrames:
495                 label = &audio_frames_label;
496                 break;
497
498         case MS_Hours:
499                 label = &ms_hours_label;
500                 break;
501         case MS_Minutes:
502                 label = &ms_minutes_label;
503                 break;
504         case MS_Seconds:
505                 label = &ms_seconds_label;
506                 break;
507
508         case Bars:
509                 label = &bars_label;
510                 break;
511         case Beats:
512                 label = &beats_label;
513                 break;
514         case Ticks:
515                 label = &ticks_label;
516                 break;
517         default:
518                 return FALSE;
519         }
520
521         switch (ev->keyval) {
522         case GDK_0:
523         case GDK_KP_0:
524                 new_char = '0';
525                 break;
526         case GDK_1:
527         case GDK_KP_1:
528                 new_char = '1';
529                 break;
530         case GDK_2:
531         case GDK_KP_2:
532                 new_char = '2';
533                 break;
534         case GDK_3:
535         case GDK_KP_3:
536                 new_char = '3';
537                 break;
538         case GDK_4:
539         case GDK_KP_4:
540                 new_char = '4';
541                 break;
542         case GDK_5:
543         case GDK_KP_5:
544                 new_char = '5';
545                 break;
546         case GDK_6:
547         case GDK_KP_6:
548                 new_char = '6';
549                 break;
550         case GDK_7:
551         case GDK_KP_7:
552                 new_char = '7';
553                 break;
554         case GDK_8:
555         case GDK_KP_8:
556                 new_char = '8';
557                 break;
558         case GDK_9:
559         case GDK_KP_9:
560                 new_char = '9';
561                 break;
562
563         case GDK_period:
564         case GDK_KP_Decimal:
565                 if (_mode == MinSec && field == MS_Seconds) {
566                         new_char = '.';
567                 } else {
568                         return FALSE;
569                 }
570                 break;
571
572         case GDK_Return:
573         case GDK_KP_Enter:
574         case GDK_Tab:
575                 move_on = true;
576                 break;
577
578         case GDK_Escape:
579                 clock_base.grab_focus ();
580                 return TRUE;
581
582         default:
583                 return FALSE;
584         }
585
586         if (!move_on) {
587
588                 if (key_entry_state == 0) {
589
590                         /* initialize with a fresh new string */
591
592                         if (field != AudioFrames) {
593                                 for (uint32_t xn = 0; xn < field_length[field] - 1; ++xn) {
594                                         new_text += '0';
595                                 }
596                         } else {
597                                 new_text = "";
598                         }
599
600                 } else {
601
602                         string existing = label->get_text();
603                         if (existing.length() >= field_length[field]) {
604                                 new_text = existing.substr (1, field_length[field] - 1);
605                         } else {
606                                 new_text = existing.substr (0, field_length[field] - 1);
607                         }
608                 }
609
610                 new_text += new_char;
611                 label->set_text (new_text);
612                 key_entry_state++;
613         }
614
615         if (key_entry_state == field_length[field]) {
616                 move_on = true;
617         }
618         
619         if (move_on) {
620
621                 if (key_entry_state) {
622       
623                         switch (field) {
624                         case SMPTE_Hours:
625                         case SMPTE_Minutes:
626                         case SMPTE_Seconds:
627                         case SMPTE_Frames:
628                                 // Check SMPTE fields for sanity (may also adjust fields)
629                                 smpte_sanitize_display();
630                                 break;
631                         default:
632                                 break;
633                         }
634                         
635                         ValueChanged(); /* EMIT_SIGNAL */
636                 }
637                 
638                 /* move on to the next field.
639                  */
640                 
641                 switch (field) {
642                         
643                         /* SMPTE */
644                         
645                 case SMPTE_Hours:
646                         minutes_ebox.grab_focus ();
647                         break;
648                 case SMPTE_Minutes:
649                         seconds_ebox.grab_focus ();
650                         break;
651                 case SMPTE_Seconds:
652                         frames_ebox.grab_focus ();
653                         break;
654                 case SMPTE_Frames:
655                         clock_base.grab_focus ();
656                         break;
657
658                 /* audio frames */
659                 case AudioFrames:
660                         clock_base.grab_focus ();
661                         break;
662
663                 /* Min:Sec */
664
665                 case MS_Hours:
666                         ms_minutes_ebox.grab_focus ();
667                         break;
668                 case MS_Minutes:
669                         ms_seconds_ebox.grab_focus ();
670                         break;
671                 case MS_Seconds:
672                         clock_base.grab_focus ();
673                         break;
674
675                 /* BBT */
676
677                 case Bars:
678                         beats_ebox.grab_focus ();
679                         break;
680                 case Beats:
681                         ticks_ebox.grab_focus ();
682                         break;
683                 case Ticks:
684                         clock_base.grab_focus ();
685                         break;
686
687                 default:
688                         break;
689                 }
690
691         }
692
693         return TRUE;
694 }
695
696 gint
697 AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field)
698 {
699         ARDOUR_UI::instance()->allow_focus (true);
700
701         key_entry_state = 0;
702
703         switch (field) {
704         case SMPTE_Hours:
705                 hours_ebox.set_flags (Gtk::HAS_FOCUS);
706                 hours_ebox.set_state (Gtk::STATE_ACTIVE);
707                 break;
708         case SMPTE_Minutes:
709                 minutes_ebox.set_flags (Gtk::HAS_FOCUS);
710                 minutes_ebox.set_state (Gtk::STATE_ACTIVE);
711                 break;
712         case SMPTE_Seconds:
713                 seconds_ebox.set_flags (Gtk::HAS_FOCUS);
714                 seconds_ebox.set_state (Gtk::STATE_ACTIVE);
715                 break;
716         case SMPTE_Frames:
717                 frames_ebox.set_flags (Gtk::HAS_FOCUS);
718                 frames_ebox.set_state (Gtk::STATE_ACTIVE);
719                 break;
720
721         case AudioFrames:
722                 audio_frames_ebox.set_flags (Gtk::HAS_FOCUS);
723                 audio_frames_ebox.set_state (Gtk::STATE_ACTIVE);
724                 break;
725
726         case MS_Hours:
727                 ms_hours_ebox.set_flags (Gtk::HAS_FOCUS);
728                 ms_hours_ebox.set_state (Gtk::STATE_ACTIVE);
729                 break;
730         case MS_Minutes:
731                 ms_minutes_ebox.set_flags (Gtk::HAS_FOCUS);
732                 ms_minutes_ebox.set_state (Gtk::STATE_ACTIVE);
733                 break;
734         case MS_Seconds:
735                 ms_seconds_ebox.set_flags (Gtk::HAS_FOCUS);
736                 ms_seconds_ebox.set_state (Gtk::STATE_ACTIVE);
737                 break;
738         case Bars:
739                 bars_ebox.set_flags (Gtk::HAS_FOCUS);
740                 bars_ebox.set_state (Gtk::STATE_ACTIVE);
741                 break;
742         case Beats:
743                 beats_ebox.set_flags (Gtk::HAS_FOCUS);
744                 beats_ebox.set_state (Gtk::STATE_ACTIVE);
745                 break;
746         case Ticks:
747                 ticks_ebox.set_flags (Gtk::HAS_FOCUS);
748                 ticks_ebox.set_state (Gtk::STATE_ACTIVE);
749                 break;
750         }
751
752         return FALSE;
753 }
754
755 gint
756 AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field)
757 {
758         ARDOUR_UI::instance()->allow_focus (false);
759
760         switch (field) {
761
762         case SMPTE_Hours:
763                 hours_ebox.unset_flags (Gtk::HAS_FOCUS);
764                 hours_ebox.set_state (Gtk::STATE_NORMAL);
765                 break;
766         case SMPTE_Minutes:
767                 minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
768                 minutes_ebox.set_state (Gtk::STATE_NORMAL);
769                 break;
770         case SMPTE_Seconds:
771                 seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
772                 seconds_ebox.set_state (Gtk::STATE_NORMAL);
773                 break;
774         case SMPTE_Frames:
775                 frames_ebox.unset_flags (Gtk::HAS_FOCUS);
776                 frames_ebox.set_state (Gtk::STATE_NORMAL);
777                 break;
778
779         case AudioFrames:
780                 audio_frames_ebox.unset_flags (Gtk::HAS_FOCUS);
781                 audio_frames_ebox.set_state (Gtk::STATE_NORMAL);
782                 break;
783
784         case MS_Hours:
785                 ms_hours_ebox.unset_flags (Gtk::HAS_FOCUS);
786                 ms_hours_ebox.set_state (Gtk::STATE_NORMAL);
787                 break;
788         case MS_Minutes:
789                 ms_minutes_ebox.unset_flags (Gtk::HAS_FOCUS);
790                 ms_minutes_ebox.set_state (Gtk::STATE_NORMAL);
791                 break;
792         case MS_Seconds:
793                 ms_seconds_ebox.unset_flags (Gtk::HAS_FOCUS);
794                 ms_seconds_ebox.set_state (Gtk::STATE_NORMAL);
795                 break;
796
797         case Bars:
798                 bars_ebox.unset_flags (Gtk::HAS_FOCUS);
799                 bars_ebox.set_state (Gtk::STATE_NORMAL);
800                 break;
801         case Beats:
802                 beats_ebox.unset_flags (Gtk::HAS_FOCUS);
803                 beats_ebox.set_state (Gtk::STATE_NORMAL);
804                 break;
805         case Ticks:
806                 ticks_ebox.unset_flags (Gtk::HAS_FOCUS);
807                 ticks_ebox.set_state (Gtk::STATE_NORMAL);
808                 break;
809         }
810
811         return FALSE;
812 }
813
814 gint
815 AudioClock::field_button_release_event (GdkEventButton *ev, Field field)
816 {
817
818
819         if (dragging) {
820                 gdk_pointer_ungrab(GDK_CURRENT_TIME);
821                 dragging = false;
822                 if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){
823                   // we actually dragged so return without setting editing focus, or we shift clicked
824
825                         return TRUE;
826                 }
827         }
828
829         if (!editable) {
830                 if (ops_menu == 0) {
831                         build_ops_menu ();
832                 }
833                 ops_menu->popup (1, ev->time);
834                 return TRUE;
835         }
836
837         if (Keyboard::is_context_menu_event (ev)) {
838                 if (ops_menu == 0) {
839                         build_ops_menu ();
840                 }
841                 ops_menu->popup (1, ev->time);
842                 return TRUE;
843         } 
844
845         switch (ev->button) {
846         case 1:
847                 switch (field) {
848                 case SMPTE_Hours:
849                         hours_ebox.grab_focus();
850                         break;
851                 case SMPTE_Minutes:
852                         minutes_ebox.grab_focus();
853                         break;
854                 case SMPTE_Seconds:
855                         seconds_ebox.grab_focus();
856                         break;
857                 case SMPTE_Frames:
858                         frames_ebox.grab_focus();
859                         break;
860
861                 case AudioFrames:
862                         audio_frames_ebox.grab_focus();
863                         break;
864                         
865                 case MS_Hours:
866                         ms_hours_ebox.grab_focus();
867                         break;
868                 case MS_Minutes:
869                         ms_minutes_ebox.grab_focus();
870                         break;
871                 case MS_Seconds:
872                         ms_seconds_ebox.grab_focus();
873                         break;
874                         
875                 case Bars:
876                         bars_ebox.grab_focus ();
877                         break;
878                 case Beats:
879                         beats_ebox.grab_focus ();
880                         break;
881                 case Ticks:
882                         ticks_ebox.grab_focus ();
883                         break;
884                 }
885                 break;
886                 
887         default:
888                 break;
889         }
890
891         return TRUE;
892 }
893
894 gint
895 AudioClock::field_button_press_event (GdkEventButton *ev, Field field)
896 {
897         if (session == 0) return FALSE;
898
899         jack_nframes_t frames = 0;
900
901         switch (ev->button) {
902         case 1:
903                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
904                         set (frames, true);
905                         ValueChanged (); /* EMIT_SIGNAL */
906                                         }
907         
908                 /* make absolutely sure that the pointer is grabbed */
909                 gdk_pointer_grab(ev->window,FALSE ,
910                                  GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK), 
911                                  NULL,NULL,ev->time);
912                 dragging = true;
913                 drag_accum = 0;
914                 drag_start_y = ev->y;
915                 drag_y = ev->y;
916                 break;
917
918         case 2:
919                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
920                         set (frames, true);
921                         ValueChanged (); /* EMIT_SIGNAL */
922                 }
923                 break;
924
925         case 3:
926                 /* used for context sensitive menu */
927                 return FALSE;
928                 break;
929
930         case 4:
931                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
932                         frames = get_frames (field);
933                         if (frames != 0) {
934                                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
935                                         frames *= 10;
936                                 }
937                                 set (current_time() + frames, true);
938                                  ValueChanged (); /* EMIT_SIGNAL */
939                         }
940                 }
941                 break;
942
943         case 5:
944                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
945                         frames = get_frames (field);
946                         if (frames != 0) {
947                                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
948                                         frames *= 10;
949                                 }
950
951                                 if ((double)current_time() - (double)frames < 0.0) {
952                                         set (0, true);
953                                 }
954                                 else {
955                                         set (current_time() - frames, true);
956                                 }
957                                 
958                                  ValueChanged (); /* EMIT_SIGNAL */
959                         }
960                 }
961                 break;
962
963         default:
964                 return FALSE;
965                 break;
966         }
967         
968         return TRUE;
969 }
970
971 gint
972 AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field)
973 {
974         if (session == 0 || !dragging) {
975                 return FALSE;
976         }
977         
978         float pixel_frame_scale_factor = 0.2f;
979
980 /*
981         if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control))  {
982                 pixel_frame_scale_factor = 0.1f;
983         }
984
985
986         if (Keyboard::modifier_state_contains (ev->state, 
987                                                Keyboard::Control|Keyboard::Alt)) {
988
989                 pixel_frame_scale_factor = 0.025f;
990         }
991 */
992         double y_delta = ev->y - drag_y;
993
994         drag_accum +=  y_delta*pixel_frame_scale_factor;
995
996         drag_y = ev->y;
997
998         if (trunc(drag_accum) != 0) {
999
1000                 jack_nframes_t frames;
1001                 jack_nframes_t pos ;
1002                 int dir;
1003                 dir = (drag_accum < 0 ? 1:-1);
1004                 pos = current_time();
1005                 frames = get_frames (field,pos,dir);
1006                 
1007                 if (frames  != 0 &&  frames * drag_accum < current_time()) {
1008                 
1009                         set ((jack_nframes_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land
1010                 
1011                 } else {
1012                         set (0 , false);
1013                 
1014                 }
1015
1016                 drag_accum= 0;
1017                 ValueChanged();  /* EMIT_SIGNAL */      
1018                 
1019
1020         }
1021
1022         return TRUE;
1023 }
1024
1025 jack_nframes_t
1026 AudioClock::get_frames (Field field,jack_nframes_t pos,int dir)
1027 {
1028
1029         jack_nframes_t frames = 0;
1030         BBT_Time bbt;
1031         switch (field) {
1032         case SMPTE_Hours:
1033                 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1034                 break;
1035         case SMPTE_Minutes:
1036                 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1037                 break;
1038         case SMPTE_Seconds:
1039                 frames = session->frame_rate();
1040                 break;
1041         case SMPTE_Frames:
1042                 frames = (jack_nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second);
1043                 break;
1044
1045         case AudioFrames:
1046                 frames = 1;
1047                 break;
1048
1049         case MS_Hours:
1050                 frames = (jack_nframes_t) floor (3600.0 * session->frame_rate());
1051                 break;
1052         case MS_Minutes:
1053                 frames = (jack_nframes_t) floor (60.0 * session->frame_rate());
1054                 break;
1055         case MS_Seconds:
1056                 frames = session->frame_rate();
1057                 break;
1058
1059         case Bars:
1060                 bbt.bars = 1;
1061                 bbt.beats = 0;
1062                 bbt.ticks = 0;
1063                 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1064                 break;
1065         case Beats:
1066                 bbt.bars = 0;
1067                 bbt.beats = 1;
1068                 bbt.ticks = 0;
1069                 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1070                 break;
1071         case Ticks:
1072                 bbt.bars = 0;
1073                 bbt.beats = 0;
1074                 bbt.ticks = 1;
1075                 frames = session->tempo_map().bbt_duration_at(pos,bbt,dir);
1076                 break;
1077         }
1078
1079         return frames;
1080 }
1081
1082 jack_nframes_t
1083 AudioClock::current_time (jack_nframes_t pos) const
1084 {
1085         jack_nframes_t ret = 0;
1086
1087         switch (_mode) {
1088         case SMPTE:
1089                 ret = smpte_frame_from_display ();
1090                 break;
1091         case BBT:
1092                 ret = bbt_frame_from_display (pos);
1093                 break;
1094
1095         case MinSec:
1096                 ret = minsec_frame_from_display ();
1097                 break;
1098
1099         case Frames:
1100                 ret = audio_frame_from_display ();
1101                 break;
1102
1103         case Off:
1104                 break;
1105         }
1106
1107         return ret;
1108 }
1109
1110 jack_nframes_t
1111 AudioClock::current_duration (jack_nframes_t pos) const
1112 {
1113         jack_nframes_t ret = 0;
1114
1115         switch (_mode) {
1116         case SMPTE:
1117                 ret = smpte_frame_from_display ();
1118                 break;
1119         case BBT:
1120                 ret = bbt_frame_duration_from_display (pos);
1121                 break;
1122
1123         case MinSec:
1124                 ret = minsec_frame_from_display ();
1125                 break;
1126
1127         case Frames:
1128                 ret = audio_frame_from_display ();
1129                 break;
1130
1131         case Off:
1132                 break;
1133         }
1134
1135         return ret;
1136 }
1137
1138 void
1139 AudioClock::smpte_sanitize_display()
1140 {
1141         // Check SMPTE fields for sanity, possibly adjusting values
1142         if (atoi(minutes_label.get_text()) > 59) {
1143                 minutes_label.set_text("59");
1144         }
1145         
1146         if (atoi(seconds_label.get_text()) > 59) {
1147                 seconds_label.set_text("59");
1148         }
1149         
1150         switch ((long)rint(session->smpte_frames_per_second)) {
1151         case 24:
1152                 if (atoi(frames_label.get_text()) > 23) {
1153                         frames_label.set_text("23");
1154                 }
1155                 break;
1156         case 25:
1157                 if (atoi(frames_label.get_text()) > 24) {
1158                         frames_label.set_text("24");
1159                 }
1160                 break;
1161         case 30:
1162                 if (atoi(frames_label.get_text()) > 29) {
1163                         frames_label.set_text("29");
1164                 }
1165                 break;
1166         default:
1167                 break;
1168         }
1169         
1170         if (session->smpte_drop_frames) {
1171                 if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
1172                         frames_label.set_text("02");
1173                 }
1174         }
1175 }
1176
1177 jack_nframes_t
1178 AudioClock::smpte_frame_from_display () const
1179 {
1180         if (session == 0) {
1181                 return 0;
1182         }
1183         
1184         SMPTE_Time smpte;
1185         jack_nframes_t sample;
1186         
1187         smpte.hours = atoi (hours_label.get_text());
1188         smpte.minutes = atoi (minutes_label.get_text());
1189         smpte.seconds = atoi (seconds_label.get_text());
1190         smpte.frames = atoi (frames_label.get_text());
1191         
1192         session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
1193         
1194
1195 #if 0
1196 #define SMPTE_SAMPLE_TEST_1
1197 #define SMPTE_SAMPLE_TEST_2
1198 #define SMPTE_SAMPLE_TEST_3
1199 #define SMPTE_SAMPLE_TEST_4
1200 #define SMPTE_SAMPLE_TEST_5
1201 #define SMPTE_SAMPLE_TEST_6
1202 #define SMPTE_SAMPLE_TEST_7
1203
1204         // Testcode for smpte<->sample conversions (P.S.)
1205         SMPTE_Time smpte1;
1206         jack_nframes_t sample1;
1207         jack_nframes_t oldsample = 0;
1208         SMPTE_Time smpte2;
1209         jack_nframes_t sample_increment;
1210
1211         sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
1212
1213 #ifdef SMPTE_SAMPLE_TEST_1
1214         // Test 1: use_offset = false, use_subframes = false
1215         cout << "use_offset = false, use_subframes = false" << endl;
1216         for (int i = 0; i < 108003; i++) {
1217                 session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
1218                 session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
1219
1220                 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1221                         cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1222                         cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1223                         cout << "sample: " << sample1 << endl;
1224                         cout << "sample: " << sample1 << " -> ";
1225                         cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1226                         break;
1227                 }
1228     
1229                 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1230                         cout << "ERROR: smpte2 not equal smpte1" << endl;
1231                         cout << "smpte1: " << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1232                         cout << "sample: " << sample1 << endl;
1233                         cout << "sample: " << sample1 << " -> ";
1234                         cout << "smpte2: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1235                         break;
1236                 }
1237                 oldsample = sample1;
1238                 session->smpte_increment( smpte1 );
1239         }
1240
1241         cout << "sample_increment: " << sample_increment << endl;
1242         cout << "sample: " << sample1 << " -> ";
1243         cout << "smpte: " << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1244 #endif
1245
1246 #ifdef SMPTE_SAMPLE_TEST_2
1247         // Test 2: use_offset = true, use_subframes = false
1248         cout << "use_offset = true, use_subframes = false" << endl;
1249   
1250         smpte1.hours = 0;
1251         smpte1.minutes = 0;
1252         smpte1.seconds = 0;
1253         smpte1.frames = 0;
1254         smpte1.subframes = 0;
1255         sample1 = oldsample = 0;
1256
1257         session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1258         cout << "Starting at sample: " << sample1 << " -> ";
1259         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1260
1261         for (int i = 0; i < 108003; i++) {
1262                 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1263                 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1264
1265 //     cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1266 //     cout << "sample: " << sample1 << endl;
1267 //     cout << "sample: " << sample1 << " -> ";
1268 //     cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1269     
1270                 if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1271                         cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1272                         cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1273                         cout << "sample: " << sample1 << endl;
1274                         cout << "sample: " << sample1 << " -> ";
1275                         cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1276                         break;
1277                 }
1278     
1279                 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1280                         cout << "ERROR: smpte2 not equal smpte1" << endl;
1281                         cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1282                         cout << "sample: " << sample1 << endl;
1283                         cout << "sample: " << sample1 << " -> ";
1284                         cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1285                         break;
1286                 }
1287                 oldsample = sample1;
1288                 session->smpte_increment( smpte1 );
1289         }
1290
1291         cout << "sample_increment: " << sample_increment << endl;
1292         cout << "sample: " << sample1 << " -> ";
1293         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1294 #endif
1295
1296 #ifdef SMPTE_SAMPLE_TEST_3
1297         // Test 3: use_offset = true, use_subframes = false, decrement
1298         cout << "use_offset = true, use_subframes = false, decrement" << endl;  
1299
1300         session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1301         cout << "Starting at sample: " << sample1 << " -> ";
1302         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1303
1304         for (int i = 0; i < 108003; i++) {
1305                 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1306                 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1307
1308 //     cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1309 //     cout << "sample: " << sample1 << endl;
1310 //     cout << "sample: " << sample1 << " -> ";
1311 //     cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1312     
1313                 if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1314                         cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1315                         cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1316                         cout << "sample: " << sample1 << endl;
1317                         cout << "sample: " << sample1 << " -> ";
1318                         cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1319                         break;
1320                 }
1321     
1322                 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1323                         cout << "ERROR: smpte2 not equal smpte1" << endl;
1324                         cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1325                         cout << "sample: " << sample1 << endl;
1326                         cout << "sample: " << sample1 << " -> ";
1327                         cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1328                         break;
1329                 }
1330                 oldsample = sample1;
1331                 session->smpte_decrement( smpte1 );
1332         }
1333
1334         cout << "sample_decrement: " << sample_increment << endl;
1335         cout << "sample: " << sample1 << " -> ";
1336         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1337 #endif
1338
1339
1340 #ifdef SMPTE_SAMPLE_TEST_4
1341         // Test 4: use_offset = true, use_subframes = true
1342         cout << "use_offset = true, use_subframes = true" << endl;
1343   
1344         for (long sub = 5; sub < 80; sub += 5) {
1345                 smpte1.hours = 0;
1346                 smpte1.minutes = 0;
1347                 smpte1.seconds = 0;
1348                 smpte1.frames = 0;
1349                 smpte1.subframes = 0;
1350                 sample1 = oldsample = (sample_increment * sub) / 80;
1351     
1352                 session->sample_to_smpte( sample1, smpte1, true /* use_offset */, true /* use_subframes */ );
1353     
1354                 cout << "starting at sample: " << sample1 << " -> ";
1355                 cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1356     
1357                 for (int i = 0; i < 108003; i++) {
1358                         session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1359                         session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1360       
1361                         if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
1362                                 cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1363                                 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1364                                 cout << "sample: " << sample1 << endl;
1365                                 cout << "sample: " << sample1 << " -> ";
1366                                 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1367                                 //break;
1368                         }
1369       
1370                         if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1371                                 cout << "ERROR: smpte2 not equal smpte1" << endl;
1372                                 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1373                                 cout << "sample: " << sample1 << endl;
1374                                 cout << "sample: " << sample1 << " -> ";
1375                                 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1376                                 break;
1377                         }
1378                         oldsample = sample1;
1379                         session->smpte_increment( smpte1 );
1380                 }
1381     
1382                 cout << "sample_increment: " << sample_increment << endl;
1383                 cout << "sample: " << sample1 << " -> ";
1384                 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1385
1386                 for (int i = 0; i < 108003; i++) {
1387                         session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
1388                         session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
1389       
1390                         if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
1391                                 cout << "ERROR: sample increment not right: " << (oldsample - sample1) << " != " << sample_increment << endl;
1392                                 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1393                                 cout << "sample: " << sample1 << endl;
1394                                 cout << "sample: " << sample1 << " -> ";
1395                                 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1396                                 //break;
1397                         }
1398       
1399                         if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames || smpte2.subframes != smpte1.subframes) {
1400                                 cout << "ERROR: smpte2 not equal smpte1" << endl;
1401                                 cout << "smpte1: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1402                                 cout << "sample: " << sample1 << endl;
1403                                 cout << "sample: " << sample1 << " -> ";
1404                                 cout << "smpte2: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1405                                 break;
1406                         }
1407                         oldsample = sample1;
1408                         session->smpte_decrement( smpte1 );
1409                 }
1410     
1411                 cout << "sample_decrement: " << sample_increment << endl;
1412                 cout << "sample: " << sample1 << " -> ";
1413                 cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1414         }
1415 #endif
1416
1417
1418 #ifdef SMPTE_SAMPLE_TEST_5
1419         // Test 5: use_offset = true, use_subframes = false, increment seconds
1420         cout << "use_offset = true, use_subframes = false, increment seconds" << endl;
1421   
1422         smpte1.hours = 0;
1423         smpte1.minutes = 0;
1424         smpte1.seconds = 0;
1425         smpte1.frames = 0;
1426         smpte1.subframes = 0;
1427         sample1 = oldsample = 0;
1428         sample_increment = session->frame_rate();
1429
1430         session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1431         cout << "Starting at sample: " << sample1 << " -> ";
1432         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1433
1434         for (int i = 0; i < 3600; i++) {
1435                 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1436                 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1437
1438 //     cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1439 //     cout << "sample: " << sample1 << endl;
1440 //     cout << "sample: " << sample1 << " -> ";
1441 //     cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1442     
1443 //     if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1444 //     {
1445 //       cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1446 //       break;
1447 //     }
1448     
1449                 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1450                         cout << "ERROR: smpte2 not equal smpte1" << endl;
1451                         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1452                         cout << "sample: " << sample1 << endl;
1453                         cout << "sample: " << sample1 << " -> ";
1454                         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1455                         break;
1456                 }
1457                 oldsample = sample1;
1458                 session->smpte_increment_seconds( smpte1 );
1459         }
1460
1461         cout << "sample_increment: " << sample_increment << endl;
1462         cout << "sample: " << sample1 << " -> ";
1463         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1464 #endif
1465
1466
1467 #ifdef SMPTE_SAMPLE_TEST_6
1468         // Test 6: use_offset = true, use_subframes = false, increment minutes
1469         cout << "use_offset = true, use_subframes = false, increment minutes" << endl;
1470   
1471         smpte1.hours = 0;
1472         smpte1.minutes = 0;
1473         smpte1.seconds = 0;
1474         smpte1.frames = 0;
1475         smpte1.subframes = 0;
1476         sample1 = oldsample = 0;
1477         sample_increment = session->frame_rate() * 60;
1478
1479         session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1480         cout << "Starting at sample: " << sample1 << " -> ";
1481         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1482
1483         for (int i = 0; i < 60; i++) {
1484                 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1485                 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1486
1487 //     cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1488 //     cout << "sample: " << sample1 << endl;
1489 //     cout << "sample: " << sample1 << " -> ";
1490 //     cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1491     
1492 //     if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1493 //     {
1494 //       cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1495 //       break;
1496 //     }
1497     
1498                 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1499                         cout << "ERROR: smpte2 not equal smpte1" << endl;
1500                         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1501                         cout << "sample: " << sample1 << endl;
1502                         cout << "sample: " << sample1 << " -> ";
1503                         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1504                         break;
1505                 }
1506                 oldsample = sample1;
1507                 session->smpte_increment_minutes( smpte1 );
1508         }
1509
1510         cout << "sample_increment: " << sample_increment << endl;
1511         cout << "sample: " << sample1 << " -> ";
1512         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1513 #endif
1514
1515 #ifdef SMPTE_SAMPLE_TEST_7
1516         // Test 7: use_offset = true, use_subframes = false, increment hours
1517         cout << "use_offset = true, use_subframes = false, increment hours" << endl;
1518   
1519         smpte1.hours = 0;
1520         smpte1.minutes = 0;
1521         smpte1.seconds = 0;
1522         smpte1.frames = 0;
1523         smpte1.subframes = 0;
1524         sample1 = oldsample = 0;
1525         sample_increment = session->frame_rate() * 60 * 60;
1526
1527         session->sample_to_smpte( sample1, smpte1, true /* use_offset */, false /* use_subframes */ );
1528         cout << "Starting at sample: " << sample1 << " -> ";
1529         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
1530
1531         for (int i = 0; i < 10; i++) {
1532                 session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
1533                 session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
1534
1535 //     cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1536 //     cout << "sample: " << sample1 << endl;
1537 //     cout << "sample: " << sample1 << " -> ";
1538 //     cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1539     
1540 //     if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1))))
1541 //     {
1542 //       cout << "ERROR: sample increment not right: " << (sample1 - oldsample) << " != " << sample_increment << endl;
1543 //       break;
1544 //     }
1545     
1546                 if (smpte2.hours != smpte1.hours || smpte2.minutes != smpte1.minutes || smpte2.seconds != smpte2.seconds || smpte2.frames != smpte1.frames) {
1547                         cout << "ERROR: smpte2 not equal smpte1" << endl;
1548                         cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
1549                         cout << "sample: " << sample1 << endl;
1550                         cout << "sample: " << sample1 << " -> ";
1551                         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1552                         break;
1553                 }
1554                 oldsample = sample1;
1555                 session->smpte_increment_hours( smpte1 );
1556         }
1557
1558         cout << "sample_increment: " << sample_increment << endl;
1559         cout << "sample: " << sample1 << " -> ";
1560         cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
1561 #endif
1562
1563 #endif  
1564
1565         return sample;
1566 }
1567
1568 jack_nframes_t
1569 AudioClock::minsec_frame_from_display () const
1570 {
1571         if (session == 0) {
1572                 return 0;
1573         }
1574
1575         int hrs = atoi (ms_hours_label.get_text());
1576         int mins = atoi (ms_minutes_label.get_text());
1577         float secs = atof (ms_seconds_label.get_text());
1578
1579         jack_nframes_t sr = session->frame_rate();
1580
1581         return (jack_nframes_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr));
1582 }
1583
1584 jack_nframes_t
1585 AudioClock::bbt_frame_from_display (jack_nframes_t pos) const
1586 {
1587         if (session == 0) {
1588                 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1589                 return 0;
1590         }
1591
1592         AnyTime any;
1593         any.type = AnyTime::BBT;
1594
1595         any.bbt.bars = atoi (bars_label.get_text());
1596         any.bbt.beats = atoi (beats_label.get_text());
1597         any.bbt.ticks = atoi (ticks_label.get_text());
1598
1599         jack_nframes_t ret = session->convert_to_frames_at (pos, any);
1600
1601         return ret;
1602 }
1603
1604
1605 jack_nframes_t
1606 AudioClock::bbt_frame_duration_from_display (jack_nframes_t pos) const
1607 {
1608         if (session == 0) {
1609                 error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg;
1610                 return 0;
1611         }
1612
1613         BBT_Time bbt;
1614
1615
1616         bbt.bars = atoi (bars_label.get_text());
1617         bbt.beats = atoi (beats_label.get_text());
1618         bbt.ticks = atoi (ticks_label.get_text());
1619         
1620         return session->tempo_map().bbt_duration_at(pos,bbt,1);
1621 }
1622
1623 jack_nframes_t
1624 AudioClock::audio_frame_from_display () const
1625 {
1626         return (jack_nframes_t) atoi (audio_frames_label.get_text());
1627 }
1628
1629 void
1630 AudioClock::build_ops_menu ()
1631 {
1632         using namespace Menu_Helpers;
1633         ops_menu = new Menu;
1634         MenuList& ops_items = ops_menu->items();
1635         ops_menu->set_name ("ArdourContextMenu");
1636
1637         Menu *mode_menu = manage (new Menu);
1638         MenuList& mode_items = mode_menu->items();
1639         mode_menu->set_name ("ArdourContextMenu");
1640         
1641         mode_items.push_back (MenuElem (_("SMPTE"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE)));
1642         mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT)));
1643         mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec)));
1644         mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames)));
1645         mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off)));
1646
1647         ops_items.push_back (MenuElem (_("Mode"), *mode_menu));
1648 }
1649
1650 void
1651 AudioClock::set_mode (Mode m)
1652 {
1653         /* slightly tricky: this is called from within the ARDOUR_UI
1654            constructor by some of its clock members. at that time
1655            the instance pointer is unset, so we have to be careful.
1656            the main idea is to drop keyboard focus in case we had
1657            started editing the clock and then we switch clock mode.
1658         */
1659
1660         if (ARDOUR_UI::instance()) {
1661                 ARDOUR_UI::instance()->allow_focus (false);
1662         }
1663
1664         if (_mode == m) {
1665                 return;
1666         }
1667         switch (_mode) {
1668         case SMPTE:
1669         case BBT:
1670         case MinSec:
1671         case Frames:
1672                 clock_base.remove ();
1673                 break;
1674         case Off:
1675                 break;
1676         }
1677         
1678         _mode = m;
1679         
1680         switch (_mode) {
1681         case SMPTE:
1682                 clock_base.add (smpte_packer_hbox);
1683                 break;
1684         case BBT:
1685                 clock_base.add (bbt_packer_hbox);
1686                 break;
1687         case MinSec:
1688                 clock_base.add (minsec_packer_hbox);
1689                 break;
1690         case Frames:
1691                 clock_base.add (frames_packer_hbox);
1692         case Off:
1693                 break;
1694         }
1695         
1696         set (last_when, true);
1697         clock_base.show_all ();
1698         key_entry_state = 0;
1699 }