diff options
author | Nick Mainsbridge <beatroute@iprimus.com.au> | 2007-01-02 13:57:06 +0000 |
---|---|---|
committer | Nick Mainsbridge <beatroute@iprimus.com.au> | 2007-01-02 13:57:06 +0000 |
commit | 1bddf1bc884feedb5deb5c35f08c7b9730936dae (patch) | |
tree | bb8ef1d1fb866027a671ce3f641ee9475804c361 | |
parent | a3a1e4b413776cf6f0d72be831a33d8a8e6048ae (diff) |
General SMPTE fixes mostly relating to non-integer frame rates. Please Test. Fix for sometimes entering an invalid SMPTE format by CHANGING THE SESSION FILE. ****Warning. the SMPTE frame rate will be reset to 30 NDF if you load an old sessionardour2_broken/***. Calculate the HMS verbose canvas cursor properly. Fix incorrect SMPTE display in clocks/VCC. Standardise size of SMPTE display in editor clocks. Make the zoom controls smaller (anyone with some smaller icons?).
git-svn-id: svn://localhost/ardour2/trunk@1257 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/ardour.menus | 4 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_options.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/audio_clock.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 27 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 129 | ||||
-rw-r--r-- | gtk2_ardour/editor_mouse.cc | 29 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration_vars.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 23 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 13 | ||||
-rw-r--r-- | libs/ardour/enums.cc | 22 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 1 | ||||
-rw-r--r-- | libs/ardour/session_midi.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 3 | ||||
-rw-r--r-- | libs/ardour/session_time.cc | 159 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 8 |
16 files changed, 281 insertions, 163 deletions
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 00188ff54f..7726add6ea 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -254,10 +254,10 @@ <menuitem action='Smpte24'/> <menuitem action='Smpte24976'/> <menuitem action='Smpte25'/> - <menuitem action='Smpte2997drop'/> <menuitem action='Smpte2997'/> - <menuitem action='Smpte30drop'/> + <menuitem action='Smpte2997drop'/> <menuitem action='Smpte30'/> + <menuitem action='Smpte30drop'/> <menuitem action='Smpte5994'/> <menuitem action='Smpte60'/> </menu> diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 8bb5782cce..b69a24e95b 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -416,9 +416,9 @@ ARDOUR_UI::map_solo_model () const char* on; if (Config->get_solo_model() == InverseMute) { - on = "SoloInPlace"; + on = X_("SoloInPlace"); } else { - on = "SoloViaBus"; + on = X_("SoloViaBus"); } Glib::RefPtr<Action> act = ActionManager::get_action ("options", on); @@ -840,7 +840,7 @@ ARDOUR_UI::parameter_changed (const char* parameter_name) map_meter_falloff (); } else if (PARAM_IS ("verify-remove-last-capture")) { ActionManager::map_some_state ("options", "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture); - } else if (PARAM_IS ("video-pullup") || PARAM_IS ("smpte-frames-per-second")) { + } else if (PARAM_IS ("video-pullup") || PARAM_IS ("smpte-format")) { if (session) { primary_clock.set (session->audible_frame(), true); secondary_clock.set (session->audible_frame(), true); diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index 87a6257fee..fb452d41cf 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -90,6 +90,9 @@ AudioClock::AudioClock (std::string name, bool allow_edit, bool duration, bool w bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo"); bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo"); + Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0); + Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0); + frames_info_box.pack_start (*frames_upper_info_label, true, true); frames_info_box.pack_start (*frames_lower_info_label, true, true); smpte_info_box.pack_start (*smpte_upper_info_label, true, true); @@ -530,7 +533,7 @@ AudioClock::set_smpte (nframes_t when, bool force) } if (smpte_upper_info_label) { - float smpte_frames = Config->get_smpte_frames_per_second(); + float smpte_frames = session->smpte_frames_per_second(); if ( fmod(smpte_frames, 1.0) == 0.0) { sprintf (buf, "%u", int (smpte_frames)); @@ -540,7 +543,7 @@ AudioClock::set_smpte (nframes_t when, bool force) smpte_upper_info_label->set_text (buf); - if (Config->get_smpte_drop_frames()) { + if (session->smpte_drop_frames()) { sprintf (buf, "DF"); } else { sprintf (buf, "NDF"); @@ -1194,7 +1197,7 @@ AudioClock::get_frames (Field field,nframes_t pos,int dir) frames = session->frame_rate(); break; case SMPTE_Frames: - frames = (nframes_t) floor (session->frame_rate() / Config->get_smpte_frames_per_second()); + frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second()); break; case AudioFrames: @@ -1302,7 +1305,7 @@ AudioClock::smpte_sanitize_display() seconds_label.set_text("59"); } - switch ((long)rint(Config->get_smpte_frames_per_second())) { + switch ((long)rint(session->smpte_frames_per_second())) { case 24: if (atoi(frames_label.get_text()) > 23) { frames_label.set_text("23"); @@ -1322,7 +1325,7 @@ AudioClock::smpte_sanitize_display() break; } - if (Config->get_smpte_drop_frames()) { + if (session->smpte_drop_frames()) { if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) { frames_label.set_text("02"); } diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 95fa048f03..1f3b9910a0 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2308,7 +2308,8 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark) const nframes_t one_second = session->frame_rate(); const nframes_t one_minute = session->frame_rate() * 60; - + const nframes_t one_smpte_second = (nframes_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame()); + nframes_t one_smpte_minute = (nframes_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame() * 60); nframes_t presnap = start; switch (snap_type) { @@ -2322,8 +2323,9 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark) start = (nframes_t) floor ((double) start / (one_second / 75)) * (one_second / 75); } break; + case SnapToSMPTEFrame: - if (direction) { + if (fmod((double)start, (double)session->frames_per_smpte_frame()) > (session->frames_per_smpte_frame() / 2)) { start = (nframes_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame()); } else { start = (nframes_t) (floor ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame()); @@ -2337,10 +2339,10 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark) } else { start -= session->smpte_offset (); } - if (direction > 0) { - start = (nframes_t) ceil ((double) start / one_second) * one_second; + if (start % one_smpte_second > one_smpte_second / 2) { + start = (nframes_t) ceil ((double) start / one_smpte_second) * one_smpte_second; } else { - start = (nframes_t) floor ((double) start / one_second) * one_second; + start = (nframes_t) floor ((double) start / one_smpte_second) * one_smpte_second; } if (session->smpte_offset_negative()) @@ -2358,10 +2360,10 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark) } else { start -= session->smpte_offset (); } - if (direction) { - start = (nframes_t) ceil ((double) start / one_minute) * one_minute; + if (start % one_smpte_minute > one_smpte_minute / 2) { + start = (nframes_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute; } else { - start = (nframes_t) floor ((double) start / one_minute) * one_minute; + start = (nframes_t) floor ((double) start / one_smpte_minute) * one_smpte_minute; } if (session->smpte_offset_negative()) { @@ -2372,7 +2374,7 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark) break; case SnapToSeconds: - if (direction) { + if (start % one_second > one_second / 2) { start = (nframes_t) ceil ((double) start / one_second) * one_second; } else { start = (nframes_t) floor ((double) start / one_second) * one_second; @@ -2380,7 +2382,7 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark) break; case SnapToMinutes: - if (direction) { + if (start % one_minute > one_minute / 2) { start = (nframes_t) ceil ((double) start / one_minute) * one_minute; } else { start = (nframes_t) floor ((double) start / one_minute) * one_minute; @@ -2612,22 +2614,25 @@ Editor::setup_toolbar () zoom_box.set_border_width (2); zoom_in_button.set_name ("EditorTimeButton"); + zoom_in_button.set_size_request(-1,16); zoom_in_button.add (*(manage (new Image (::get_icon("zoom_in"))))); zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false)); ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom In")); zoom_out_button.set_name ("EditorTimeButton"); + zoom_out_button.set_size_request(-1,16); zoom_out_button.add (*(manage (new Image (::get_icon("zoom_out"))))); zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true)); ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom Out")); zoom_out_full_button.set_name ("EditorTimeButton"); + zoom_out_full_button.set_size_request(-1,16); zoom_out_full_button.add (*(manage (new Image (::get_icon("zoom_full"))))); zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session)); ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session")); zoom_focus_selector.set_name ("ZoomFocusSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Edit Cursor", 2+FUDGE, 0); + Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Edit Cursor", FUDGE, 0); set_popdown_strings (zoom_focus_selector, zoom_focus_strings); zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus")); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 5aa0ca5624..dd35d36c05 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -296,7 +296,7 @@ class Editor : public PublicEditor /* SMPTE timecode & video sync */ - void smpte_fps_chosen (ARDOUR::Session::SmpteFormat format); + void smpte_fps_chosen (ARDOUR::SmpteFormat format); void video_pullup_chosen (ARDOUR::Session::PullupFormat pullup); void subframes_per_frame_chosen (uint32_t); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index cc45d6b769..f99a828203 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -380,16 +380,16 @@ Editor::register_actions () RadioAction::Group smpte_group; - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte23976"), _("23.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_23976)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte24"), _("24"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_24)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte24976"), _("24.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_24976)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte25"), _("25"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_25)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte2997"), _("29.97"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_2997)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte2997drop"), _("29.97 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_2997drop)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte30"), _("30"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_30)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte30drop"), _("30 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_30drop)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte5994"), _("59.94"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_5994)); - ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte60"), _("60"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_60)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte23976"), _("23.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_23976)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte24"), _("24"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_24)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte24976"), _("24.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_24976)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte25"), _("25"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_25)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte2997"), _("29.97"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_2997)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte2997drop"), _("29.97 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_2997drop)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte30"), _("30"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_30)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte30drop"), _("30 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_30drop)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte5994"), _("59.94"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_5994)); + ActionManager::register_radio_action (editor_actions, smpte_group, X_("Smpte60"), _("60"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_60)); RadioAction::Group pullup_group; @@ -502,33 +502,37 @@ Editor::update_smpte_mode () RefPtr<Action> act; const char* action = 0; - float frames = Config->get_smpte_frames_per_second(); - bool drop = Config->get_smpte_drop_frames(); - - if ((frames < 23.976 * 1.0005) && !drop) + switch (Config->get_smpte_format()) { + case smpte_23976: action = X_("Smpte23976"); - else if ((frames < 24 * 1.0005) && !drop) + break; + case smpte_24: action = X_("Smpte24"); - else if ((frames < 24.976 * 1.0005) && !drop) + break; + case smpte_24976: action = X_("Smpte24976"); - else if ((frames < 25 * 1.0005) && !drop) + break; + case smpte_25: action = X_("Smpte25"); - else if ((frames < 29.97 * 1.0005) && !drop) + break; + case smpte_2997: action = X_("Smpte2997"); - else if ((frames < 29.97 * 1.0005) && drop) + break; + case smpte_2997drop: action = X_("Smpte2997drop"); - else if ((frames < 30 * 1.0005) && !drop) + break; + case smpte_30: action = X_("Smpte30"); - else if ((frames < 30 * 1.0005) && drop) + break; + case smpte_30drop: action = X_("Smpte30drop"); - else if ((frames < 59.94 * 1.0005) && !drop) + break; + case smpte_5994: action = X_("Smpte5994"); - else if ((frames < 60 * 1.0005) && !drop) + break; + case smpte_60: action = X_("Smpte60"); - else { - fatal << string_compose (_("programming error: Unexpected SMPTE value (%1, drop = %2) in update_smpte_mode. Menu is probably wrong."), - frames, drop) << endmsg; - /*NOTREACHED*/ + break; } act = ActionManager::get_action (X_("Editor"), action); @@ -837,7 +841,7 @@ Editor::zoom_focus_chosen (ZoomFocus focus) } void -Editor::smpte_fps_chosen (Session::SmpteFormat format) +Editor::smpte_fps_chosen (SmpteFormat format) { /* this is driven by a toggle on a radio group, and so is invoked twice, once for the item that became inactive and once for the one that became @@ -846,62 +850,39 @@ Editor::smpte_fps_chosen (Session::SmpteFormat format) if (session) { - float fps = 10; - bool drop = false; - RefPtr<Action> act; switch (format) { - case Session::smpte_23976: { - fps=23.976; - drop = false; + case smpte_23976: act = ActionManager::get_action (X_("Editor"), X_("Smpte23976")); - } break; - case Session::smpte_24: { - fps=24; - drop = false; + break; + case smpte_24: act = ActionManager::get_action (X_("Editor"), X_("Smpte24")); - } break; - case Session::smpte_24976: { - fps=24.976; - drop = false; + break; + case smpte_24976: act = ActionManager::get_action (X_("Editor"), X_("Smpte24976")); - } break; - case Session::smpte_25: { - fps=25; - drop = false; + break; + case smpte_25: act = ActionManager::get_action (X_("Editor"), X_("Smpte25")); - } break; - case Session::smpte_2997: { - fps=29.97; - drop = false; + break; + case smpte_2997: act = ActionManager::get_action (X_("Editor"), X_("Smpte2997")); - } break; - case Session::smpte_2997drop: { - fps=29.97; - drop = true; + break; + case smpte_2997drop: act = ActionManager::get_action (X_("Editor"), X_("Smpte2997drop")); - } break; - case Session::smpte_30: { - fps=30; - drop = false; + break; + case smpte_30: act = ActionManager::get_action (X_("Editor"), X_("Smpte30")); - } break; - case Session::smpte_30drop: { - fps=30; - drop = true; + break; + case smpte_30drop: act = ActionManager::get_action (X_("Editor"), X_("Smpte30drop")); - } break; - case Session::smpte_5994: { - fps=59.94; - drop = false; + break; + case smpte_5994: act = ActionManager::get_action (X_("Editor"), X_("Smpte5994")); - } break; - case Session::smpte_60: { - fps=60; - drop = false; + break; + case smpte_60: act = ActionManager::get_action (X_("Editor"), X_("Smpte60")); - } break; + break; default: cerr << "Editor received unexpected smpte type" << endl; } @@ -909,7 +890,7 @@ Editor::smpte_fps_chosen (Session::SmpteFormat format) if (act) { RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act); if (ract && ract->get_active()) { - session->set_smpte_type (fps, drop); + session->set_smpte_format (format); } } } @@ -1081,8 +1062,8 @@ Editor::parameter_changed (const char* parameter_name) update_punch_range_view (true); } else if (PARAM_IS ("layer-model")) { update_layering_model (); - } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) { - update_smpte_mode (); + } else if (PARAM_IS ("smpte-format")) { + update_smpte_mode (); update_just_smpte (); } else if (PARAM_IS ("video-pullup")) { update_video_pullup (); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 4752ae16a2..78867bba25 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -3512,6 +3512,8 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d char buf[128]; SMPTE::Time smpte; BBT_Time bbt; + int hours, mins; + nframes_t frame_rate; float secs; if (session == 0) { @@ -3530,10 +3532,14 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d break; case AudioClock::MinSec: - /* XXX fix this to compute min/sec properly */ - session->smpte_time (frame, smpte); - secs = smpte.seconds + ((float) smpte.frames / Config->get_smpte_frames_per_second()); - snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs); + /* XXX this is copied from show_verbose_duration_cursor() */ + frame_rate = session->frame_rate(); + hours = frame / (frame_rate * 3600); + frame = frame % (frame_rate * 3600); + mins = frame / (frame_rate * 60); + frame = frame % (frame_rate * 60); + secs = (float) frame / (float) frame_rate; + snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs); break; default: @@ -3557,6 +3563,8 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off SMPTE::Time smpte; BBT_Time sbbt; BBT_Time ebbt; + int hours, mins; + nframes_t distance, frame_rate; float secs; Meter meter_at_start(session->tempo_map().meter_at(start)); @@ -3597,10 +3605,15 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off break; case AudioClock::MinSec: - /* XXX fix this to compute min/sec properly */ - session->smpte_duration (end - start, smpte); - secs = smpte.seconds + ((float) smpte.frames / Config->get_smpte_frames_per_second()); - snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs); + /* XXX this stuff should be elsewhere.. */ + distance = end - start; + frame_rate = session->frame_rate(); + hours = distance / (frame_rate * 3600); + distance = distance % (frame_rate * 3600); + mins = distance / (frame_rate * 60); + distance = distance % (frame_rate * 60); + secs = (float) distance / (float) frame_rate; + snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs); break; default: diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 67f4362095..ad7e44d332 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -95,11 +95,10 @@ CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true) /* timecode and sync */ CONFIG_VARIABLE (bool, jack_time_master, "jack-time-master", true) +CONFIG_VARIABLE (SmpteFormat, smpte_format, "smpte-format", smpte_30) CONFIG_VARIABLE (bool, use_video_sync, "use-video-sync", false) CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true) -CONFIG_VARIABLE (float, smpte_frames_per_second, "smpte-frames-per-second", 30.0f) CONFIG_VARIABLE (float, video_pullup, "video-pullup", 0.0f) -CONFIG_VARIABLE (bool, smpte_drop_frames, "smpte-drop-frames", false) /* metering */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a10cbfff95..c71403e125 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -378,6 +378,9 @@ class Session : public PBD::StatefulDestructible double frames_per_smpte_frame() const { return _frames_per_smpte_frame; } nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; } + float smpte_frames_per_second() const; + bool smpte_drop_frames() const; + /* Locations */ Locations *locations() { return &_locations; } @@ -480,19 +483,6 @@ class Session : public PBD::StatefulDestructible nframes_t transport_frame () const {return _transport_frame; } nframes_t audible_frame () const; - enum SmpteFormat { - smpte_23976, - smpte_24, - smpte_24976, - smpte_25, - smpte_2997, - smpte_2997drop, - smpte_30, - smpte_30drop, - smpte_5994, - smpte_60, - }; - enum PullupFormat { pullup_Plus4Plus1, pullup_Plus4, @@ -502,11 +492,10 @@ class Session : public PBD::StatefulDestructible pullup_Minus1, pullup_Minus4Plus1, pullup_Minus4, - pullup_Minus4Minus1, + pullup_Minus4Minus1 }; - int set_smpte_type (float fps, bool drop_frames); - + int set_smpte_format (SmpteFormat); void sync_time_vars(); void bbt_time (nframes_t when, BBT_Time&); @@ -1300,7 +1289,7 @@ class Session : public PBD::StatefulDestructible nframes_t _smpte_frames_per_hour; nframes_t _smpte_offset; bool _smpte_offset_negative; - + /* cache the most-recently requested time conversions. this helps when we have multiple clocks showing the same time (e.g. the transport frame) diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 27ff8e93da..4fe8a54f71 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -145,6 +145,18 @@ namespace ARDOUR { } }; + enum SmpteFormat { + smpte_23976, + smpte_24, + smpte_24976, + smpte_25, + smpte_2997, + smpte_2997drop, + smpte_30, + smpte_30drop, + smpte_5994, + smpte_60 + }; struct AnyTime { enum Type { @@ -343,6 +355,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::CrossfadeModel& sf); std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf); std::istream& operator>>(std::istream& o, ARDOUR::ShuttleBehaviour& sf); std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& sf); +std::istream& operator>>(std::istream& o, ARDOUR::SmpteFormat& sf); static inline nframes_t session_frame_to_track_frame (nframes_t session_frame, double speed) diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 293fface5a..32f195e2ac 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -43,7 +43,7 @@ setup_enum_writer () mute_type _mute_type; Session::RecordState _Session_RecordState; Session::Event::Type _Session_Event_Type; - Session::SmpteFormat _Session_SmpteFormat; + SmpteFormat _Session_SmpteFormat; Session::PullupFormat _Session_PullupFormat; AudioRegion::FadeShape _AudioRegion_FadeShape; Panner::LinkDirection _Panner_LinkDirection; @@ -222,16 +222,16 @@ setup_enum_writer () REGISTER_CLASS_ENUM (Session, InCleanup); REGISTER_BITS (_Session_StateOfTheState); - REGISTER_CLASS_ENUM (Session, smpte_23976); - REGISTER_CLASS_ENUM (Session, smpte_24); - REGISTER_CLASS_ENUM (Session, smpte_24976); - REGISTER_CLASS_ENUM (Session, smpte_25); - REGISTER_CLASS_ENUM (Session, smpte_2997); - REGISTER_CLASS_ENUM (Session, smpte_2997drop); - REGISTER_CLASS_ENUM (Session, smpte_30); - REGISTER_CLASS_ENUM (Session, smpte_30drop); - REGISTER_CLASS_ENUM (Session, smpte_5994); - REGISTER_CLASS_ENUM (Session, smpte_60); + REGISTER_ENUM (smpte_23976); + REGISTER_ENUM (smpte_24); + REGISTER_ENUM (smpte_24976); + REGISTER_ENUM (smpte_25); + REGISTER_ENUM (smpte_2997); + REGISTER_ENUM (smpte_2997drop); + REGISTER_ENUM (smpte_30); + REGISTER_ENUM (smpte_30drop); + REGISTER_ENUM (smpte_5994); + REGISTER_ENUM (smpte_60); REGISTER (_Session_SmpteFormat); REGISTER_CLASS_ENUM (Session, pullup_Plus4Plus1); diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 274b0f1d3c..3344c61a9a 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -622,4 +622,5 @@ std::istream& operator>>(std::istream& o, CrossfadeModel& var) { return int_to_t std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type<SlaveSource> (o, var); } std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) { return int_to_type<ShuttleBehaviour> (o, var); } std::istream& operator>>(std::istream& o, ShuttleUnits& var) { return int_to_type<ShuttleUnits> (o, var); } +std::istream& operator>>(std::istream& o, SmpteFormat& var) { return int_to_type<SmpteFormat> (o, var); } diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index fe08b40127..e4e3d82b68 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -565,7 +565,7 @@ Session::mmc_step (MIDI::MachineControl &mmc, int steps) } double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0); - double cur_speed = (((steps * 0.5) * Config->get_smpte_frames_per_second()) / diff_secs) / Config->get_smpte_frames_per_second(); + double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second(); if (_transport_speed == 0 || cur_speed * _transport_speed < 0) { /* change direction */ diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index fb15de15c4..0afa682d58 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -3020,7 +3020,6 @@ Session::config_changed (const char* parameter_name) for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { if ((*i)->record_enabled ()) { - //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (!Config->get_auto_input()); } } @@ -3080,7 +3079,7 @@ Session::config_changed (const char* parameter_name) setup_raid_path (Config->get_raid_path()); - } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) { + } else if (PARAM_IS ("smpte-format")) { sync_time_vars (); diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc index 61051e4632..e7bd0a3696 100644 --- a/libs/ardour/session_time.cc +++ b/libs/ardour/session_time.cc @@ -48,25 +48,127 @@ Session::bbt_time (nframes_t when, BBT_Time& bbt) } /* SMPTE TIME */ +float +Session::smpte_frames_per_second() const +{ + switch (Config->get_smpte_format()) { + case smpte_23976: + return 23.976; + + break; + case smpte_24: + return 24; + + break; + case smpte_24976: + return 24.976; + + break; + case smpte_25: + return 25; + + break; + case smpte_2997: + return 29.97; + + break; + case smpte_2997drop: + return 29.97; + + break; + case smpte_30: + return 30; + + break; + case smpte_30drop: + return 30; + + break; + case smpte_5994: + return 59.94; + + break; + case smpte_60: + return 60; + + break; + default: + cerr << "Editor received unexpected smpte type" << endl; + } + return 30.0; +} +bool +Session::smpte_drop_frames() const +{ + switch (Config->get_smpte_format()) { + case smpte_23976: + return false; + + break; + case smpte_24: + return false; + + break; + case smpte_24976: + return false; + + break; + case smpte_25: + return false; + + break; + case smpte_2997: + return false; + break; + case smpte_2997drop: + return true; + + break; + case smpte_30: + return false; + + break; + case smpte_30drop: + return true; + + break; + case smpte_5994: + return false; + + break; + case smpte_60: + return false; + + break; + default: + cerr << "Editor received unexpected smpte type" << endl; + } + return false; +} void Session::sync_time_vars () { _current_frame_rate = (nframes_t) round (_base_frame_rate * (1.0 + (Config->get_video_pullup()/100.0))); - _frames_per_hour = _current_frame_rate * 3600; - _frames_per_smpte_frame = (double) _current_frame_rate / (double) Config->get_smpte_frames_per_second(); - _smpte_frames_per_hour = (unsigned long) (Config->get_smpte_frames_per_second() * 3600.0); + _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second(); + if (smpte_drop_frames()) { + _frames_per_hour = (long)(107892 * _frames_per_smpte_frame); + } else { + _frames_per_hour = (long)(3600 * rint(smpte_frames_per_second()) * _frames_per_smpte_frame); + } + _smpte_frames_per_hour = (nframes_t)rint(smpte_frames_per_second() * 3600.0); + } int -Session::set_smpte_type (float fps, bool drop_frames) +Session::set_smpte_format (SmpteFormat format) { - Config->set_smpte_frames_per_second (fps); - Config->set_smpte_drop_frames (drop_frames); + + Config->set_smpte_format (format); last_smpte_valid = false; // smpte type bits are the middle two in the upper nibble - switch ((int) ceil (fps)) { + switch ((int) ceil (smpte_frames_per_second())) { case 24: mtc_smpte_bits = 0; break; @@ -77,7 +179,7 @@ Session::set_smpte_type (float fps, bool drop_frames) case 30: default: - if (drop_frames) { + if (smpte_drop_frames()) { mtc_smpte_bits = 0x40; } else { mtc_smpte_bits = 0x60; @@ -109,7 +211,8 @@ Session::set_smpte_offset_negative (bool neg) void Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset, bool use_subframes ) const { - if (Config->get_smpte_drop_frames()) { + + if (smpte.drop) { // The drop frame format was created to better approximate the 30000/1001 = 29.97002997002997.... // framerate of NTSC color TV. The used frame rate of drop frame is 29.97, which drifts by about // 0.108 frame per hour, or about 1.3 frames per 12 hours. This is not perfect, but a lot better @@ -148,9 +251,10 @@ Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset // 0:10:00:00 0.0 0 600.000 26460000 (accurate) // // Per Sigmond <per@sigmond.no> - + // Samples inside time dividable by 10 minutes (real time accurate) - nframes_t base_samples = ((smpte.hours * 60 * 60) + ((smpte.minutes / 10) * 10 * 60)) * frame_rate(); + nframes_t base_samples = (nframes_t) (((smpte.hours * 107892) + ((smpte.minutes / 10) * 17982)) * _frames_per_smpte_frame); + // Samples inside time exceeding the nearest 10 minutes (always offset, see above) long exceeding_df_minutes = smpte.minutes % 10; long exceeding_df_seconds = (exceeding_df_minutes * 60) + smpte.seconds; @@ -158,8 +262,14 @@ Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset nframes_t exceeding_samples = (nframes_t) rint(exceeding_df_frames * _frames_per_smpte_frame); sample = base_samples + exceeding_samples; } else { - // Non drop is easy: - sample = (((smpte.hours * 60 * 60) + (smpte.minutes * 60) + smpte.seconds) * frame_rate()) + (nframes_t)rint(smpte.frames * _frames_per_smpte_frame); + /* + Non drop is easy.. just note the use of + rint(smpte.rate) * _frames_per_smpte_frame + (frames per SMPTE second), which is larger than + frame_rate() in the non-integer SMPTE rate case. + */ + + sample = (nframes_t)rint((((smpte.hours * 60 * 60) + (smpte.minutes * 60) + smpte.seconds) * (rint(smpte.rate) * _frames_per_smpte_frame)) + (smpte.frames * _frames_per_smpte_frame)); } if (use_subframes) { @@ -186,6 +296,7 @@ Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset } } } + } @@ -220,7 +331,7 @@ Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset, // high sample numbers in the calculations that follow. smpte.hours = offset_sample / _frames_per_hour; offset_sample = offset_sample % _frames_per_hour; - + // Calculate exact number of (exceeding) smpte frames and fractional frames smpte_frames_left_exact = (double) offset_sample / _frames_per_smpte_frame; smpte_frames_fraction = smpte_frames_left_exact - floor( smpte_frames_left_exact ); @@ -236,7 +347,7 @@ Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset, // Extract hour-exceeding frames for minute, second and frame calculations smpte_frames_left = ((long) floor( smpte_frames_left_exact )); - if (Config->get_smpte_drop_frames()) { + if (smpte_drop_frames()) { // See long explanation in smpte_to_sample()... // Number of 10 minute chunks @@ -272,18 +383,18 @@ Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset, } } else { // Non drop is easy - smpte.minutes = smpte_frames_left / ((long) Config->get_smpte_frames_per_second () * 60); - smpte_frames_left = smpte_frames_left % ((long) Config->get_smpte_frames_per_second () * 60); - smpte.seconds = smpte_frames_left / (long) Config->get_smpte_frames_per_second (); - smpte.frames = smpte_frames_left % (long) Config->get_smpte_frames_per_second (); + smpte.minutes = smpte_frames_left / ((long) rint (smpte_frames_per_second ()) * 60); + smpte_frames_left = smpte_frames_left % ((long) rint (smpte_frames_per_second ()) * 60); + smpte.seconds = smpte_frames_left / (long) rint(smpte_frames_per_second ()); + smpte.frames = smpte_frames_left % (long) rint(smpte_frames_per_second ()); } if (!use_subframes) { smpte.subframes = 0; } /* set frame rate and drop frame */ - smpte.rate = Config->get_smpte_frames_per_second (); - smpte.drop = Config->get_smpte_drop_frames(); + smpte.rate = smpte_frames_per_second (); + smpte.drop = smpte_drop_frames(); } void @@ -414,7 +525,7 @@ Session::jack_timebase_callback (jack_transport_state_t state, #ifdef HAVE_JACK_VIDEO_SUPPORT //poke audio video ratio so Ardour can track Video Sync - pos->audio_frames_per_video_frame = frame_rate() / Config->get_smpte_frames_per_second (); + pos->audio_frames_per_video_frame = frame_rate() / smpte_frames_per_second(); pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio); #endif @@ -422,7 +533,7 @@ Session::jack_timebase_callback (jack_transport_state_t state, /* SMPTE info */ t.smpte_offset = _smpte_offset; - t.smpte_frame_rate = Config->get_smpte_frames_per_second (); + t.smpte_frame_rate = smpte_frames_per_second(); if (_transport_speed) { @@ -473,7 +584,7 @@ Session::convert_to_frames_at (nframes_t position, AnyTime& any) secs = any.smpte.hours * 60 * 60; secs += any.smpte.minutes * 60; secs += any.smpte.seconds; - secs += any.smpte.frames / Config->get_smpte_frames_per_second (); + secs += any.smpte.frames / smpte_frames_per_second(); if (_smpte_offset_negative) { return (nframes_t) floor (secs * frame_rate()) - _smpte_offset; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 0ff94324bb..e86c30dd4d 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -924,7 +924,10 @@ TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num) return frame_time (the_beat); - /* XXX just keeping this for reference + + + /***************************** + XXX just keeping this for reference TempoMap::BBTPointList::iterator i; TempoMap::BBTPointList *more_zoomed_bbt_points; @@ -978,7 +981,8 @@ TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num) delete more_zoomed_bbt_points; return fr ; - */ + ******************************/ + } |