master merge; new files not added after initial cairocanvas patch application
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 5 Apr 2013 21:16:33 +0000 (17:16 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 5 Apr 2013 21:16:33 +0000 (17:16 -0400)
31 files changed:
doc/region_ops.txt
gtk2_ardour/ardour.menus.in
gtk2_ardour/ardour_ui.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_videotimeline.cc
gtk2_ardour/export_video_dialog.cc
gtk2_ardour/export_video_dialog.h
gtk2_ardour/hit.cc [new file with mode: 0644]
gtk2_ardour/hit.h [new file with mode: 0644]
gtk2_ardour/note_base.cc [new file with mode: 0644]
gtk2_ardour/note_base.h [new file with mode: 0644]
gtk2_ardour/nsm.cc
gtk2_ardour/nsm.h
gtk2_ardour/public_editor.h
gtk2_ardour/rhythm_ferret.cc
gtk2_ardour/route_time_axis.cc
gtk2_ardour/sys_ex.cc [new file with mode: 0644]
gtk2_ardour/sys_ex.h [new file with mode: 0644]
gtk2_ardour/system_exec.cc
gtk2_ardour/transcode_ffmpeg.cc
gtk2_ardour/video_monitor.cc
gtk2_ardour/video_monitor.h
gtk2_ardour/video_timeline.cc
gtk2_ardour/video_timeline.h
libs/ardour/midi_clock_slave.cc
libs/ardour/session_process.cc
libs/canvas/canvas/fwd.h [new file with mode: 0644]
libs/evoral/evoral/Sequence.hpp

index 69851bf3ebdc5494126cf230e9b714c01d0d526c..c6b4ab00e5aeef5745beae30f4a5a28086fb1ed0 100644 (file)
@@ -24,9 +24,8 @@ If the edit point is `mouse':
      if the mouse is over a selected region, or no region, this method returns all selected regions.
      if the mouse is over an unselected region, just that region is returned.
 
-For other edit points the method returns the selected regions AND those that are both under the edit position
-AND on a selected track, or on a track which is in the same active edit-enabled route group as a selected
-region.
+For other edit points the method returns the selected regions. If no regions are selected, it returns 
+the regions under the edit position on the selected tracks.
 
 The action handlers call the appropriate method to decide which regions to operate on.
 
index 608f4dd6e4f4147426f1aeca897778eab1b7b565..e50f62cfbb745a1a93dafb855bea5967ab810b45 100644 (file)
 #ifdef WITH_VIDEOTIMELINE
         <separator/>
         <menuitem action="toggle-video-ruler"/>
+      </menu>
+      <menu action="VideoMonitorMenu">
+        <menuitem action="zoom-vmon-100"/>
+        <menuitem action="toggle-vmon-letterbox"/>
+        <separator/>
+        <menuitem action="toggle-vmon-ontop"/>
+        <menuitem action="toggle-vmon-fullscreen"/>
+        <separator/>
+        <menuitem action="toggle-vmon-timecode"/>
+        <menuitem action="toggle-vmon-frame"/>
+        <menuitem action="toggle-vmon-osdbg"/>
 #endif
       </menu>
       <menu action="ScrollMenu">
index 4c1be5f674de643db0aa01ea58ca05cf5d9b47b1..1022acee2d082440387188ea2e9cb84edfa2d834 100644 (file)
@@ -660,22 +660,28 @@ ARDOUR_UI::startup ()
        app->ready ();
 
        nsm_url = getenv ("NSM_URL");
+       nsm = 0;
 
        if (nsm_url) {
                nsm = new NSM_Client;
                if (!nsm->init (nsm_url)) {
                        nsm->announce (PROGRAM_NAME, ":dirty:", "ardour3");
 
+                       unsigned int i = 0;
                        // wait for announce reply from nsm server
-                       do {
+                       for ( i = 0; i < 5000; ++i) {
                                nsm->check ();
-                               usleep (10);
-                       } while (!nsm->is_active ());
+                               usleep (i);
+                               if (nsm->is_active())
+                                       break;
+                       }
                        // wait for open command from nsm server
-                       do {
+                       for ( i = 0; i < 5000; ++i) {
                                nsm->check ();
-                               usleep (10);
-                       } while (!nsm->client_id ());
+                               usleep (1000);
+                               if (nsm->client_id ())
+                                       break;
+                       }
 
                        if (_session && nsm) {
                                _session->set_nsm_state( nsm->is_active() );
@@ -698,12 +704,6 @@ ARDOUR_UI::startup ()
                                }
                        }
 
-                       // wait for session is loaded reply from nsm server
-                       do {
-                               nsm->check ();
-                               usleep (10);
-                       } while (!nsm->session_loaded ());
-
                }
                else {
                        delete nsm;
@@ -981,7 +981,7 @@ ARDOUR_UI::every_second ()
        update_disk_space ();
        update_timecode_format ();
 
-       if (nsm && nsm->is_active () && nsm->session_loaded ()) {
+       if (nsm && nsm->is_active ()) {
                nsm->check ();
 
                if (!_was_dirty && _session->dirty ()) {
index bde5b658931c00909d8fabd9adb3f2ed7f047494..194c3442410bb1bdbd44bc5f51f97cd1eb68adc5 100644 (file)
@@ -4040,7 +4040,7 @@ Editor::restore_editing_space ()
 
 /**
  *  Make new playlists for a given track and also any others that belong
- *  to the same active route group with the `edit' property.
+ *  to the same active route group with the `select' property.
  *  @param v Track.
  */
 
@@ -4056,7 +4056,7 @@ Editor::new_playlists (TimeAxisView* v)
 
 /**
  *  Use a copy of the current playlist for a given track and also any others that belong
- *  to the same active route group with the `edit' property.
+ *  to the same active route group with the `select' property.
  *  @param v Track.
  */
 
@@ -4071,7 +4071,7 @@ Editor::copy_playlists (TimeAxisView* v)
 }
 
 /** Clear the current playlist for a given track and also any others that belong
- *  to the same active route group with the `edit' property.
+ *  to the same active route group with the `select' property.
  *  @param v Track.
  */
 
@@ -4592,32 +4592,16 @@ Editor::get_regions_after (RegionSelection& rs, framepos_t where, const TrackVie
        }
 }
 
-/** Start with regions that are selected.  Then add equivalent regions
- *  on tracks in the same active edit-enabled route group as any of
- *  the regions that we started with.
- */
-
-RegionSelection
-Editor::get_regions_from_selection ()
-{
-       return get_equivalent_regions (selection->regions, ARDOUR::Properties::select.property_id);
-}
-
 /** Get regions using the following method:
  *
- *  Make an initial region list using the selected regions, unless
+ *  Make a region list using the selected regions, unless
  *  the edit point is `mouse' and the mouse is over an unselected
- *  region.  In this case, start with just that region.
- *
- *  Then, add equivalent regions in active edit groups to the region list.
- *
- *  Then, search the list of selected tracks to find any selected tracks which
- *  do not contain regions already in the region list. If there are no selected
- *  tracks and 'No Selection = All Tracks' is active, search all tracks rather
- *  than just the selected.
+ *  region.  In this case, use just that region.
  *
- *  Add any regions that are under the edit point on these tracks to get the
- *  returned region list.
+ *  If the edit point is not 'mouse', and there are no regions selected,
+ *  search the list of selected tracks and return regions that are under
+ *  the edit point on these tracks. If there are no selected tracks and
+ *  'No Selection = All Tracks' is active, search all tracks,
  *
  *  The rationale here is that the mouse edit point is special in that
  *  its position describes both a time and a track; the other edit
@@ -4639,48 +4623,25 @@ Editor::get_regions_from_selection_and_edit_point ()
                regions = selection->regions;
        }
 
-       TrackViewList tracks;
 
-       if (_edit_point != EditAtMouse) {
-               tracks = selection->tracks;
-       }
+       if (regions.empty() && _edit_point != EditAtMouse) {
+               TrackViewList tracks = selection->tracks;
 
-       /* Add any other regions that are in the same
-          edit-activated route group as one of our regions.
-        */
-       regions = get_equivalent_regions (regions, ARDOUR::Properties::select.property_id);
-       framepos_t const where = get_preferred_edit_position ();
-
-       if (_route_groups->all_group_active_button().get_active() && tracks.empty()) {
-               /* tracks is empty (no track selected), and 'No Selection = All Tracks'
-                * is enabled, so consider all tracks
-                */
-               tracks = track_views; 
-       }
-
-       if (!tracks.empty()) {
-               /* now search the selected tracks for tracks which don't
-                  already contain regions to be acted upon, and get regions at
-                  the edit point on those tracks too.
-                */
-               TrackViewList tracks_without_relevant_regions;
-
-               for (TrackViewList::iterator t = tracks.begin (); t != tracks.end (); ++t) {
-                       if (!regions.involves (**t)) {
-                               /* there are no equivalent regions on this track */
-                               tracks_without_relevant_regions.push_back (*t);
-                       }
+               if (_route_groups->all_group_active_button().get_active() && tracks.empty()) {
+                       /* tracks is empty (no track selected), and 'No Selection = All Tracks'
+                        * is enabled, so consider all tracks
+                        */
+                       tracks = track_views; 
                }
 
-               if (!tracks_without_relevant_regions.empty()) {
-                       /* there are some selected tracks with neither selected
-                        * regions or their equivalents: act upon all regions in
-                        * those tracks
-                        */
-                       get_regions_at (regions, where, tracks_without_relevant_regions);
+               if (!tracks.empty()) {
+                       /* no region selected or entered, but some selected tracks:
+                        * act on all regions on the selected tracks at the edit point
+                        *
+                       framepos_t const where = get_preferred_edit_position ();
+                       get_regions_at(regions, where, tracks);
                }
        }
-
        return regions;
 }
 
@@ -4698,7 +4659,7 @@ Editor::get_regions_from_selection_and_entered ()
                regions.add (entered_regionview);
        }
 
-       return get_equivalent_regions (regions, ARDOUR::Properties::select.property_id);
+       return regions;
 }
 
 void
index 3adcfc8ab423674ca5b6b5d6d296cfdeb159cbff..43d3fccedf9217d654296771d92cfd523fec7136 100644 (file)
@@ -929,9 +929,18 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        ArdourCanvas::Group*      videotl_group;
        Glib::RefPtr<Gtk::ToggleAction> ruler_video_action;
        Glib::RefPtr<Gtk::ToggleAction> xjadeo_proc_action;
+       Glib::RefPtr<Gtk::ToggleAction> xjadeo_ontop_action;
+       Glib::RefPtr<Gtk::ToggleAction> xjadeo_timecode_action;
+       Glib::RefPtr<Gtk::ToggleAction> xjadeo_frame_action;
+       Glib::RefPtr<Gtk::ToggleAction> xjadeo_osdbg_action;
+       Glib::RefPtr<Gtk::ToggleAction> xjadeo_fullscreen_action;
+       Glib::RefPtr<Gtk::ToggleAction> xjadeo_letterbox_action;
+       Glib::RefPtr<Gtk::Action> xjadeo_zoom_100;
        void set_xjadeo_proc ();
        void toggle_xjadeo_proc (int state=-1);
        void set_xjadeo_sensitive (bool onoff);
+       void set_xjadeo_viewoption (int);
+       void toggle_xjadeo_viewoption (int what, int state=-1);
        void toggle_ruler_video (bool onoff) {ruler_video_action->set_active(onoff);}
        int videotl_bar_height; /* in units of timebar_height; default: 4 */
        int get_videotl_bar_height () const { return videotl_bar_height; }
@@ -2040,7 +2049,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        void get_regions_at (RegionSelection&, framepos_t where, const TrackViewList& ts) const;
        void get_regions_after (RegionSelection&, framepos_t where, const TrackViewList& ts) const;
 
-       RegionSelection get_regions_from_selection ();
        RegionSelection get_regions_from_selection_and_edit_point ();
        RegionSelection get_regions_from_selection_and_entered ();
 
index 0fe99582ca36068e0eba4cfd0ee9d0900074f808..1efc3585136faa8ef27088eb33f92d4fa1b91058 100644 (file)
@@ -547,8 +547,19 @@ Editor::register_actions ()
        ruler_timecode_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-timecode-ruler"), _("Timecode"), sigc::bind (sigc::mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_timecode)));
        ruler_minsec_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-minsec-ruler"), _("Min:Sec"), sigc::bind (sigc::mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_minsec)));
 #ifdef WITH_VIDEOTIMELINE
+
+       ActionManager::register_action (editor_menu_actions, X_("VideoMonitorMenu"), _("Video Monitor"));
+
        ruler_video_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-video-ruler"), _("Video"), sigc::bind (sigc::mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_video_timeline)));
-       xjadeo_proc_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("ToggleJadeo"), _("Show Video Monitor"), sigc::mem_fun (*this, &Editor::set_xjadeo_proc)));
+       xjadeo_proc_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("ToggleJadeo"), _("Video Monitor"), sigc::mem_fun (*this, &Editor::set_xjadeo_proc)));
+
+       xjadeo_ontop_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-ontop"), _("Always on Top"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 1)));
+       xjadeo_timecode_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-timecode"), _("Timecode"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 2)));
+       xjadeo_frame_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-frame"), _("Framenumber"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 3)));
+       xjadeo_osdbg_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-osdbg"), _("Timecode Background"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 4)));
+       xjadeo_fullscreen_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-fullscreen"), _("Fullscreen"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 5)));
+       xjadeo_letterbox_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-letterbox"), _("Letterbox"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 6)));
+       xjadeo_zoom_100 = reg_sens (editor_actions, "zoom-vmon-100", _("Original Size"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 7));
 
 #endif
 
@@ -565,6 +576,19 @@ Editor::register_actions ()
        ruler_video_action->set_active (false);
        xjadeo_proc_action->set_active (false);
        xjadeo_proc_action->set_sensitive (false);
+       xjadeo_ontop_action->set_active (false);
+       xjadeo_ontop_action->set_sensitive (false);
+       xjadeo_timecode_action->set_active (false);
+       xjadeo_timecode_action->set_sensitive (false);
+       xjadeo_frame_action->set_active (false);
+       xjadeo_frame_action->set_sensitive (false);
+       xjadeo_osdbg_action->set_active (false);
+       xjadeo_osdbg_action->set_sensitive (false);
+       xjadeo_fullscreen_action->set_active (false);
+       xjadeo_fullscreen_action->set_sensitive (false);
+       xjadeo_letterbox_action->set_active (false);
+       xjadeo_letterbox_action->set_sensitive (false);
+       xjadeo_zoom_100->set_sensitive (false);
 #endif
        if (Profile->get_sae()) {
                ruler_bbt_action->set_active (true);
@@ -763,6 +787,7 @@ Editor::set_xjadeo_sensitive (bool onoff)
 {
        xjadeo_proc_action->set_sensitive(onoff);
 }
+
 void
 Editor::toggle_xjadeo_proc (int state)
 {
@@ -777,6 +802,14 @@ Editor::toggle_xjadeo_proc (int state)
                        xjadeo_proc_action->set_active(!xjadeo_proc_action->get_active());
                        break;
        }
+       bool onoff = xjadeo_proc_action->get_active();
+       xjadeo_ontop_action->set_sensitive(onoff);
+       xjadeo_timecode_action->set_sensitive(onoff);
+       xjadeo_frame_action->set_sensitive(onoff);
+       xjadeo_osdbg_action->set_sensitive(onoff);
+       xjadeo_fullscreen_action->set_sensitive(onoff);
+       xjadeo_letterbox_action->set_sensitive(onoff);
+       xjadeo_zoom_100->set_sensitive(onoff);
 }
 
 void
@@ -788,6 +821,84 @@ Editor::set_xjadeo_proc ()
                ARDOUR_UI::instance()->video_timeline->close_video_monitor();
        }
 }
+
+void
+Editor::toggle_xjadeo_viewoption (int what, int state)
+{
+       Glib::RefPtr<Gtk::ToggleAction> action;
+       switch (what) {
+               case 1:
+                       action = xjadeo_ontop_action;
+                       break;
+               case 2:
+                       action = xjadeo_timecode_action;
+                       break;
+               case 3:
+                       action = xjadeo_frame_action;
+                       break;
+               case 4:
+                       action = xjadeo_osdbg_action;
+                       break;
+               case 5:
+                       action = xjadeo_fullscreen_action;
+                       break;
+               case 6:
+                       action = xjadeo_letterbox_action;
+                       break;
+               case 7:
+                       return;
+               default:
+                       return;
+       }
+
+       switch(state) {
+               case 1:
+                       action->set_active(true);
+                       break;
+               case 0:
+                       action->set_active(false);
+                       break;
+               default:
+                       action->set_active(!action->get_active());
+                       break;
+       }
+}
+
+void
+Editor::set_xjadeo_viewoption (int what)
+{
+       Glib::RefPtr<Gtk::ToggleAction> action;
+       switch (what) {
+               case 1:
+                       action = xjadeo_ontop_action;
+                       break;
+               case 2:
+                       action = xjadeo_timecode_action;
+                       break;
+               case 3:
+                       action = xjadeo_frame_action;
+                       break;
+               case 4:
+                       action = xjadeo_osdbg_action;
+                       break;
+               case 5:
+                       action = xjadeo_fullscreen_action;
+                       break;
+               case 6:
+                       action = xjadeo_letterbox_action;
+                       break;
+               case 7:
+                       ARDOUR_UI::instance()->video_timeline->control_video_monitor(what, 0);
+                       return;
+               default:
+                       return;
+       }
+       if (action->get_active()) {
+               ARDOUR_UI::instance()->video_timeline->control_video_monitor(what, 1);
+       } else {
+               ARDOUR_UI::instance()->video_timeline->control_video_monitor(what, 0);
+       }
+}
 #endif
 
 void
index 7fed4fc410c9e39df2f4316ae940460b3658f5a2..9eb0a4c2bd0eda175a0b9fe386a3eacf31102046 100644 (file)
@@ -3737,7 +3737,7 @@ Editor::cut_copy (CutCopyOp op)
        /* we only want to cut regions if some are selected */
 
        if (!selection->regions.empty()) {
-               rs = get_regions_from_selection ();
+               rs = selection->regions;
        }
 
        switch (effective_mouse_mode()) {
index a58a896fdd6f0341e4bfb0af82fc1da3b851959f..564e3016e78be7d2f6cedd8e65e8664269de757c 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "ardour/profile.h"
 #include "ardour/rc_configuration.h"
+#include "ardour/audio_track.h"
+#include "ardour/audioregion.h"
 
 #include "ardour_ui.h"
 #include "editor.h"
@@ -33,6 +35,7 @@
 #include "video_image_frame.h"
 #include "export_video_dialog.h"
 #include "export_video_infobox.h"
+#include "interthread_progress_window.h"
 
 #include "i18n.h"
 
@@ -95,11 +98,27 @@ Editor::embed_audio_from_video (std::string path, framepos_t n)
        vector<std::string> paths;
        paths.push_back(path);
 #if 0
-       do_embed (paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, n);
-#else
        do_import (paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, ARDOUR::SrcBest, n);
-       unlink(path.c_str());
+#else
+       current_interthread_info = &import_status;
+       import_status.current = 1;
+       import_status.total = paths.size ();
+       import_status.all_done = false;
+
+       ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import"));
+       ipw.show ();
+
+       boost::shared_ptr<ARDOUR::Track> track;
+       bool ok = (import_sndfiles (paths, Editing::ImportAsTrack, ARDOUR::SrcBest, n, 1, 1, track, false) == 0);
+       if (ok && track) {
+               boost::shared_ptr<ARDOUR::Playlist> pl = track->playlist();
+               pl->find_next_region(n, ARDOUR::End, 0)->set_video_locked(true);
+               _session->save_state ("");
+       }
+
+       import_status.all_done = true;
 #endif
+       unlink(path.c_str());
 }
 
 void
index 380b8240f7e3a89844c1231491382b2bdfed6925..03b64cfbe387bab32061739647b6adbd54faa9d8 100644 (file)
@@ -66,21 +66,21 @@ using namespace ARDOUR;
 ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
        : ArdourDialog (_("Export Video File "))
        , editor (ed)
-       , outfn_path_label (_("Output File:"), Gtk::ALIGN_LEFT)
+       , outfn_path_label (_("File:"), Gtk::ALIGN_LEFT)
        , outfn_browse_button (_("Browse"))
-       , invid_path_label (_("Input Video File:"), Gtk::ALIGN_LEFT)
+       , invid_path_label (_("Video:"), Gtk::ALIGN_LEFT)
        , invid_browse_button (_("Browse"))
        , transcode_button (_("Export"))
        , abort_button (_("Abort"))
        , scale_checkbox (_("Scale Video (W x H):"))
-       , width_adjustment (128, 768, 1920, 1, 16, 0)
+       , width_adjustment (768, 128, 1920, 1, 16, 0)
        , width_spinner (width_adjustment)
-       , height_adjustment (128, 576, 1920, 1, 16, 0)
+       , height_adjustment (576, 128, 1920, 1, 16, 0)
        , height_spinner (height_adjustment)
        , aspect_checkbox (_("Set Aspect Ratio:"))
        , normalize_checkbox (_("Normalize Audio"))
        , twopass_checkbox (_("2 Pass Encoding"))
-       , optimizations_checkbox (_("Optimizations:"))
+       , optimizations_checkbox (_("Codec Optimizations:"))
        , optimizations_label ("-")
        , deinterlace_checkbox (_("Deinterlace"))
        , bframes_checkbox (_("Use [2] B-frames (MPEG 2 or 4 only)"))
@@ -92,7 +92,6 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
 {
        set_session (s);
 
-
        set_name ("ExportVideoDialog");
        set_position (Gtk::WIN_POS_MOUSE);
        set_modal (true);
@@ -117,29 +116,32 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
        }
        delete transcoder; transcoder = 0;
 
-       l = manage (new Label (_("<b>Files:</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+       l = manage (new Label (_("<b>Output:</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
        l->set_use_markup ();
-       vbox->pack_start (*l, false, false);
+       vbox->pack_start (*l, false, false, 4);
 
        path_hbox = manage (new HBox);
        path_hbox->pack_start (outfn_path_label, false, false, 3);
        path_hbox->pack_start (outfn_path_entry, true, true, 3);
        path_hbox->pack_start (outfn_browse_button, false, false, 3);
-       outfn_browse_button.set_name ("PaddedButton");
-       vbox->pack_start (*path_hbox, false, false);
+       vbox->pack_start (*path_hbox, false, false, 2);
+
+       l = manage (new Label (_("<b>Input:</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+       l->set_use_markup ();
+       vbox->pack_start (*l, false, false, 4);
 
        path_hbox = manage (new HBox);
        path_hbox->pack_start (invid_path_label, false, false, 3);
        path_hbox->pack_start (invid_path_entry, true, true, 3);
        path_hbox->pack_start (invid_browse_button, false, false, 3);
-       invid_browse_button.set_name ("PaddedButton");
-       vbox->pack_start (*path_hbox, false, false);
+       vbox->pack_start (*path_hbox, false, false, 2);
 
        path_hbox = manage (new HBox);
-       l = manage (new Label (_("Input Audio (Ardour Session):"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       path_hbox->pack_start (*l, true, true, 3);
-       path_hbox->pack_start (insnd_combo, true, true, 3);
-       vbox->pack_start (*path_hbox, false, false);
+       l = manage (new Label (_("Audio:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+       path_hbox->pack_start (*l, false, false, 3);
+       l = manage (new Label (_("Master Bus"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+       path_hbox->pack_start (*l, false, false, 2);
+       vbox->pack_start (*path_hbox, false, false, 2);
 
        insnd_combo.set_name ("PaddedButton");
        insnd_combo.append_text("from ardour session-start to session-end");
@@ -168,43 +170,47 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
        l->set_use_markup ();
        options_box->pack_start (*l, false, true, 4);
 
-       Table* t = manage (new Table (4, 11));
+       Table* t = manage (new Table (4, 12));
        t->set_spacings (4);
+       int ty = 0;
        options_box->pack_start (*t, true, true, 4);
+       l = manage (new Label (_("Range:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+       t->attach (*l, 0, 1, ty, ty+1);
+       t->attach (insnd_combo, 1, 4, ty, ty+1); ty++;
        l = manage (new Label (_("Preset:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       t->attach (*l, 0, 1, 0, 1);
-       t->attach (preset_combo, 1, 4, 0, 1);
+       t->attach (*l, 0, 1, ty, ty+1);
+       t->attach (preset_combo, 1, 4, ty, ty+1); ty++;
        l = manage (new Label (_("Video Codec:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       t->attach (*l, 0, 1, 1, 2);
-       t->attach (video_codec_combo, 1, 2, 1, 2);
+       t->attach (*l, 0, 1, ty, ty+1);
+       t->attach (video_codec_combo, 1, 2, ty, ty+1);
        l = manage (new Label (_("Video KBit/s:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       t->attach (*l, 2, 3, 1, 2);
-       t->attach (video_bitrate_combo, 3, 4, 1, 2);
+       t->attach (*l, 2, 3, ty, ty+1);
+       t->attach (video_bitrate_combo, 3, 4, ty, ty+1); ty++;
        l = manage (new Label (_("Audio Codec:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       t->attach (*l, 0, 1, 2, 3);
-       t->attach (audio_codec_combo, 1, 2, 2, 3);
+       t->attach (*l, 0, 1, ty, ty+1);
+       t->attach (audio_codec_combo, 1, 2, ty, ty+1);
        l = manage (new Label (_("Audio KBit/s:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       t->attach (*l, 2, 3, 2, 3);
-       t->attach (audio_bitrate_combo, 3, 4, 2, 3);
+       t->attach (*l, 2, 3, ty, ty+1);
+       t->attach (audio_bitrate_combo, 3, 4, ty, ty+1); ty++;
        l = manage (new Label (_("Audio Samplerate:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
-       t->attach (*l, 0, 1, 3, 4);
-       t->attach (audio_samplerate_combo, 1, 2, 3, 4);
-       t->attach (normalize_checkbox, 2, 4, 3, 4);
-       t->attach (scale_checkbox, 0, 2, 4, 5);
-       t->attach (width_spinner, 2, 3, 4, 5);
-       t->attach (height_spinner, 3, 4, 4, 5);
-       t->attach (fps_checkbox, 0, 3, 5, 6);
-       t->attach (fps_combo, 3, 4, 5, 6);
-       t->attach (aspect_checkbox, 2, 3, 6, 7);
-       t->attach (aspect_combo, 3, 4, 6, 7);
-       t->attach (twopass_checkbox, 0, 2, 6, 7);
-       t->attach (bframes_checkbox, 0, 2, 7, 8);
-       t->attach (deinterlace_checkbox, 2, 4, 7, 8);
-       t->attach (meta_checkbox, 2, 4, 8, 9);
-       t->attach (optimizations_checkbox, 0, 1, 9, 10);
-       t->attach (optimizations_label, 1, 4, 9, 10);
+       t->attach (*l, 0, 1, ty, ty+1);
+       t->attach (audio_samplerate_combo, 1, 2, ty, ty+1);
+       t->attach (normalize_checkbox, 2, 4, ty, ty+1); ty++;
+       t->attach (scale_checkbox, 0, 2, ty, ty+1);
+       t->attach (width_spinner, 2, 3, ty, ty+1);
+       t->attach (height_spinner, 3, 4, ty, ty+1); ty++;
+       t->attach (fps_checkbox, 0, 3, ty, ty+1);
+       t->attach (fps_combo, 3, 4, ty, ty+1); ty++;
+       t->attach (twopass_checkbox, 0, 2, ty, ty+1);
+       t->attach (aspect_checkbox, 2, 3, ty, ty+1);
+       t->attach (aspect_combo, 3, 4, ty, ty+1); ty++;
+       t->attach (bframes_checkbox, 0, 2, ty, ty+1);
+       t->attach (deinterlace_checkbox, 2, 4, ty, ty+1); ty++;
+       t->attach (meta_checkbox, 2, 4, ty, ty+1); ty++;
+       t->attach (optimizations_checkbox, 0, 1, ty, ty+1);
+       t->attach (optimizations_label, 1, 4, ty, ty+1); ty++;
 #if 1 /* tentative debug mode */
-       t->attach (debug_checkbox, 0, 4, 10, 11);
+       t->attach (debug_checkbox, 0, 4, ty, ty+1); ty++;
 #endif
 
        preset_combo.set_name ("PaddedButton");
@@ -293,7 +299,7 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
        fps_checkbox_toggled();
        video_codec_combo_changed();
 
-       vbox->pack_start (*options_box, false, true);
+       vbox->pack_start (*options_box, false, true, 4);
        get_vbox()->set_spacing (4);
        get_vbox()->pack_start (*vbox, false, false);
 
@@ -344,9 +350,41 @@ ExportVideoDialog::update_progress (framecnt_t c, framecnt_t a)
        if (a == 0 || c > a) {
                pbar.set_pulse_step(.1);
                pbar.pulse();
-               return;
+       } else {
+               double progress = (double)c / (double) a;
+               progress = progress / ((twopass ? 2.0 : 1.0) + (normalize ? 2.0 : 1.0));
+               if (normalize && twopass) progress += (firstpass ? .5 : .75);
+               else if (normalize) progress += 2.0/3.0;
+               else if (twopass) progress += (firstpass ? 1.0/3.0 : 2.0/3.0);
+               else progress += .5;
+
+               pbar.set_fraction (progress);
        }
-       pbar.set_fraction ((double)c / (double) a);
+}
+
+
+gint
+ExportVideoDialog::audio_progress_display ()
+{
+       std::string status_text;
+       double progress = 0.0;
+               if (status->normalizing) {
+                       pbar.set_text (_("Normalizing audio"));
+                       progress = ((float) status->current_normalize_cycle) / status->total_normalize_cycles;
+                       progress = progress / (twopass ? 4.0 : 3.0) + (twopass ? .25 : 1.0/3.0);
+               } else {
+                       pbar.set_text (_("Exporting audio"));
+                       progress = ((float) status->processed_frames_current_timespan) / status->total_frames_current_timespan;
+                       progress = progress / ((twopass ? 2.0 : 1.0) + (normalize ? 2.0 : 1.0));
+               }
+               if (progress < previous_progress) {
+                       // Work around gtk bug
+                       pbar.hide();
+                       pbar.show();
+               }
+               previous_progress = progress;
+               pbar.set_fraction (progress);
+       return TRUE;
 }
 
 void
@@ -355,10 +393,9 @@ ExportVideoDialog::finished ()
        if (aborted) {
                unlink(outfn_path_entry.get_text().c_str());
                unlink (insnd.c_str());
-               warning << _("Video Export Failed or Was Aborted") << endmsg;
                Gtk::Dialog::response(RESPONSE_CANCEL);
-       } else if (twopass) {
-               twopass = false;
+       } else if (twopass && firstpass) {
+               firstpass = false;
                if (transcoder) { delete transcoder; transcoder = 0;}
                encode_pass(2);
        } else {
@@ -386,6 +423,8 @@ ExportVideoDialog::launch_export ()
        progress_box->show();
        aborted = false;
        twopass = twopass_checkbox.get_active();
+       firstpass = true;
+       normalize = normalize_checkbox.get_active();
 
        /* export audio track */
        ExportTimespanPtr tsp = _session->get_export_handler()->add_timespan();
@@ -394,7 +433,7 @@ ExportVideoDialog::launch_export ()
        boost::shared_ptr<AudioGrapher::BroadcastInfo> b;
        XMLTree tree;
        std::string vtl_samplerate = audio_samplerate_combo.get_active_text();
-       std::string vtl_normalize = normalize_checkbox.get_active()?"true":"false";
+       std::string vtl_normalize = normalize ? "true" : "false";
        tree.read_buffer(std::string(
 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
 "<ExportFormatSpecification name=\"VTL-WAV-16\" id=\"3094591e-ccb9-4385-a93f-c9955ffeb1f0\">"
@@ -486,34 +525,19 @@ ExportVideoDialog::launch_export ()
        /* do sound export */
        _session->get_export_handler()->add_export_config (tsp, ccp, fmp, fnp, b);
        _session->get_export_handler()->do_export();
-       boost::shared_ptr<ARDOUR::ExportStatus> status = _session->get_export_status ();
-       //status->running = true;
+       status = _session->get_export_status ();
 
-       float previous_progress = 0.0;
+       audio_progress_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ExportVideoDialog::audio_progress_display), 100);
+       previous_progress = 0.0;
        while (status->running) {
                if (aborted) { status->abort(); }
-
-               float progress = 0.0;
-               if (status->normalizing) {
-                       pbar.set_text (_("Normalizing audio"));
-                       progress = ((float) status->current_normalize_cycle) / status->total_normalize_cycles;
-               } else {
-                       pbar.set_text (_("Exporting audio"));
-                       progress = ((float) status->processed_frames_current_timespan) / status->total_frames_current_timespan;
-               }
-               if (progress < previous_progress) {
-                       // Work around gtk bug
-                       pbar.hide();
-                       pbar.show();
-               }
-               previous_progress = progress;
-               pbar.set_fraction (progress);
                if (gtk_events_pending()) {
                        gtk_main_iteration ();
                } else {
                        usleep (10000);
                }
        }
+       audio_progress_connection.disconnect();
        status->finish ();
        if (status->aborted()) {
                unlink (insnd.c_str());
@@ -775,7 +799,6 @@ ExportVideoDialog::video_codec_combo_changed ()
 {
        if ((  video_codec_combo.get_active_text() == "mpeg4"
             ||video_codec_combo.get_active_text() == "mpeg2video"
-            ||video_codec_combo.get_active_text() == "flv"
                        ) && !(
               preset_combo.get_active_text() == "dvd-PAL"
             ||preset_combo.get_active_text() == "dvd-NTSC"
@@ -888,14 +911,14 @@ ExportVideoDialog::preset_combo_changed ()
        if (p == "dvd-PAL" || p == "dvd-NTSC") {
                for (it = c.begin(); it != c.end(); ++it) {
                        int row = it->get_top_attach();
-                       if (row ==1 || row ==2 || row==4 || row==5 || row == 8) {
+                       if (row == 2 || row == 3 || row== 5 || row== 6 || row == 9) {
                                it->get_widget()->hide();
                        }
                }
        } else {
                for (it = c.begin(); it != c.end(); ++it) {
                        int row = it->get_top_attach();
-                       if (row ==1 || row ==2 || row==4 || row==5 || row == 8) {
+                       if (row == 2 || row == 3 || row== 5 || row== 6 || row == 9) {
                                it->get_widget()->show();
                        }
                }
index ae0beafd37ff0484ba67cb8de0b23b9e94bc7be7..72376512d12dd332238ed2578e96e7239a95a373 100644 (file)
@@ -66,10 +66,17 @@ class ExportVideoDialog : public ArdourDialog , public PBD::ScopedConnectionList
 
        bool aborted;
        bool twopass;
+       bool firstpass;
+       bool normalize;
 
        void finished ();
        void update_progress (ARDOUR::framecnt_t, ARDOUR::framecnt_t);
 
+       boost::shared_ptr<ARDOUR::ExportStatus> status;
+       sigc::connection audio_progress_connection;
+       gint audio_progress_display ();
+       float previous_progress;
+
        TranscodeFfmpeg *transcoder;
        std::string insnd;
 
diff --git a/gtk2_ardour/hit.cc b/gtk2_ardour/hit.cc
new file mode 100644 (file)
index 0000000..a7d1a9b
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+    Copyright (C) 2007 Paul Davis
+    Author: Dave Robillard
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "evoral/Note.hpp"
+#include "canvas/polygon.h"
+#include "midi_region_view.h"
+#include "public_editor.h"
+#include "utils.h"
+#include "hit.h"
+
+using namespace ARDOUR;
+using namespace ArdourCanvas;
+
+Hit::Hit (
+       MidiRegionView&                   region,
+       Group*                            group,
+       double                            /*size*/,
+       const boost::shared_ptr<NoteType> note,
+       bool with_events) 
+       : NoteBase (region, with_events, note)
+{
+       _polygon = new Polygon (group);
+       set_item (_polygon);
+}
+
+void
+Hit::move_event (double dx, double dy)
+{
+       _polygon->move (Duple (dx, dy));
+}
+
+Coord
+Hit::x0 () const
+{
+       boost::optional<Rect> bbox = _polygon->bounding_box ();
+       assert (bbox);
+       return bbox.get().x0;
+}
+
+Coord
+Hit::x1 () const
+{
+       boost::optional<Rect> bbox = _polygon->bounding_box ();
+       assert (bbox);
+       return bbox.get().x1;
+}
+
+Coord
+Hit::y0 () const
+{
+       boost::optional<Rect> bbox = _polygon->bounding_box ();
+       assert (bbox);
+       return bbox.get().y0;
+}
+
+Coord
+Hit::y1 () const
+{
+       boost::optional<Rect> bbox = _polygon->bounding_box ();
+       assert (bbox);
+       return bbox.get().y1;
+}
+
+void
+Hit::set_outline_color (uint32_t color)
+{
+       _polygon->set_outline_color (color);
+}
+
+void
+Hit::set_fill_color (uint32_t color)
+{
+       _polygon->set_fill_color (color);
+}
+
+void
+Hit::show ()
+{
+       _polygon->show ();
+}
+
+void
+Hit::hide ()
+{
+       _polygon->hide ();
+}
+
+void
+Hit::set_height (Distance /*height*/)
+{
+       /* XXX */
+}
+
+void
+Hit::set_position (Duple position)
+{
+       _polygon->set_position (position);
+}
diff --git a/gtk2_ardour/hit.h b/gtk2_ardour/hit.h
new file mode 100644 (file)
index 0000000..3afdd91
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+    Copyright (C) 2007 Paul Davis
+    Author: Dave Robillard
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __gtk_ardour_hit_h__
+#define __gtk_ardour_hit_h__
+
+#include <iostream>
+#include "note_base.h"
+
+namespace ArdourCanvas {
+       class Polygon;
+}
+
+class Hit : public NoteBase
+{
+public:
+       typedef Evoral::Note<double> NoteType;
+
+       Hit (
+               MidiRegionView&                   region,
+               ArdourCanvas::Group*              group,
+               double                            size,
+               const boost::shared_ptr<NoteType> note = boost::shared_ptr<NoteType>(),
+               bool with_events = true);
+
+       void show ();
+       void hide ();
+
+       ArdourCanvas::Coord x0 () const;
+       ArdourCanvas::Coord y0 () const;
+       ArdourCanvas::Coord x1 () const;
+       ArdourCanvas::Coord y1 () const;
+
+       void set_position (ArdourCanvas::Duple);
+
+       void set_height (ArdourCanvas::Coord);
+
+       void set_outline_color (uint32_t);
+       void set_fill_color (uint32_t);
+
+       void move_event (double, double);
+
+private:
+       ArdourCanvas::Polygon* _polygon;
+};
+
+#endif /* __gtk_ardour_hit_h__ */
diff --git a/gtk2_ardour/note_base.cc b/gtk2_ardour/note_base.cc
new file mode 100644 (file)
index 0000000..b8587e1
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+    Copyright (C) 2007 Paul Davis
+    Author: David Robillard
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <iostream>
+
+#include "gtkmm2ext/keyboard.h"
+
+#include "canvas/text.h"
+
+#include "note_base.h"
+#include "midi_region_view.h"
+#include "public_editor.h"
+#include "editing_syms.h"
+#include "keyboard.h"
+
+using namespace std;
+using namespace Gtkmm2ext;
+using ARDOUR::MidiModel;
+using namespace ArdourCanvas;
+
+PBD::Signal1<void,NoteBase*> NoteBase::NoteBaseDeleted;
+
+/// dividing the hue circle in 16 parts, hand adjusted for equal look, courtesy Thorsten Wilms
+const uint32_t NoteBase::midi_channel_colors[16] = {
+         0xd32d2dff,  0xd36b2dff,  0xd3972dff,  0xd3d12dff,
+         0xa0d32dff,  0x7dd32dff,  0x2dd45eff,  0x2dd3c4ff,
+         0x2da5d3ff,  0x2d6fd3ff,  0x432dd3ff,  0x662dd3ff,
+         0x832dd3ff,  0xa92dd3ff,  0xd32dbfff,  0xd32d67ff
+       };
+
+NoteBase::NoteBase(MidiRegionView& region, bool with_events, const boost::shared_ptr<NoteType> note)
+       : _region(region)
+       , _item (0)
+       , _text(0)
+//     , _channel_selector_widget()
+       , _state(None)
+       , _note(note)
+       , _with_events (with_events)
+       , _selected(false)
+       , _valid (true)
+       , _mouse_x_fraction (-1.0)
+       , _mouse_y_fraction (-1.0)
+{
+}
+
+NoteBase::~NoteBase()
+{
+       NoteBaseDeleted (this);
+
+       delete _text;
+
+       /* XXX */
+//     delete _channel_selector_widget;
+}
+
+void
+NoteBase::set_item (Item* item)
+{
+       _item = item;
+       _item->set_data ("notebase", this);
+
+       if (_with_events) {
+               _item->Event.connect (sigc::mem_fun (*this, &NoteBase::event_handler));
+       }
+}
+
+void
+NoteBase::invalidate ()
+{
+       _valid = false;
+}
+
+void
+NoteBase::validate ()
+{
+       _valid = true;
+}
+
+void
+NoteBase::show_velocity()
+{
+       if (!_text) {
+               _text = new Text (_item->parent ());
+               _text->set_ignore_events (true);
+               _text->set_color (ARDOUR_UI::config()->canvasvar_MidiNoteVelocityText.get());
+               _text->set_alignment (Pango::ALIGN_CENTER);
+       }
+
+       _text->set_x_position ((x0() + x1()) / 2);
+       _text->set_y_position ((y0() + y1()) / 2);
+       ostringstream velo(ios::ate);
+       velo << int(_note->velocity());
+       _text->set (velo.str ());
+       _text->show();
+       _text->raise_to_top();
+}
+
+void
+NoteBase::hide_velocity()
+{
+       delete _text;
+       _text = 0;
+}
+
+void
+NoteBase::on_channel_selection_change(uint16_t selection)
+{
+       // make note change its color if its channel is not marked active
+       if ( (selection & (1 << _note->channel())) == 0 ) {
+               set_fill_color(ARDOUR_UI::config()->canvasvar_MidiNoteInactiveChannel.get());
+               set_outline_color(calculate_outline(ARDOUR_UI::config()->canvasvar_MidiNoteInactiveChannel.get()));
+       } else {
+               // set the color according to the notes selection state
+               set_selected(_selected);
+       }
+       // this forces the item to update..... maybe slow...
+       _item->hide();
+       _item->show();
+}
+
+void
+NoteBase::on_channel_change(uint8_t channel)
+{
+       _region.note_selected(this, true);
+       hide_channel_selector();
+       _region.change_channel(channel);
+}
+
+void
+NoteBase::show_channel_selector ()
+{
+#if 0  
+       if (_channel_selector_widget == 0) {
+         
+               if(_region.channel_selector_scoped_note() != 0){
+                   _region.channel_selector_scoped_note()->hide_channel_selector();
+                   _region.set_channel_selector_scoped_note(0);
+               }
+
+               SingleMidiChannelSelector* _channel_selector = new SingleMidiChannelSelector(_note->channel());
+               _channel_selector->show_all();
+               _channel_selector->channel_selected.connect(
+                       sigc::mem_fun(this, &NoteBase::on_channel_change));
+
+               _channel_selector->clicked.connect (
+                       sigc::mem_fun (this, &NoteBase::hide_channel_selector));
+
+               _channel_selector_widget = new Widget(*(_item->property_parent()),
+                                                     x1(),
+                                                     y2() + 2,
+                                                     (Gtk::Widget &) *_channel_selector);
+
+               _channel_selector_widget->hide();
+               _channel_selector_widget->property_height() = 100;
+               _channel_selector_widget->property_width() = 100;
+               _channel_selector_widget->raise_to_top();
+               _channel_selector_widget->show();
+               
+               _region.set_channel_selector_scoped_note(this);
+       } else {
+               hide_channel_selector();
+       }
+#endif 
+}
+
+void
+NoteBase::hide_channel_selector ()
+{
+#if 0
+       if (_channel_selector_widget) {
+               _channel_selector_widget->hide();
+               delete _channel_selector_widget;
+               _channel_selector_widget = 0;
+       }
+#endif 
+}
+
+void
+NoteBase::set_selected(bool selected)
+{
+       if (!_note) {
+               return;
+       }
+
+       _selected = selected;
+       set_fill_color (base_color ());
+        
+       if (_selected) {
+               set_outline_color(calculate_outline(ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get()));
+               
+               if(_region.channel_selector_scoped_note() != 0){
+                   _region.channel_selector_scoped_note()->hide_channel_selector();
+                   _region.set_channel_selector_scoped_note(0);
+               }
+       } else {
+               set_outline_color(calculate_outline(base_color()));
+               hide_channel_selector();
+       }
+
+}
+
+#define SCALE_USHORT_TO_UINT8_T(x) ((x) / 257)
+
+uint32_t
+NoteBase::base_color()
+{
+       using namespace ARDOUR;
+
+       ColorMode mode = _region.color_mode();
+
+       const uint8_t min_opacity = 15;
+       uint8_t       opacity = std::max(min_opacity, uint8_t(_note->velocity() + _note->velocity()));
+
+       switch (mode) {
+       case TrackColor:
+       {
+               Gdk::Color color = _region.midi_stream_view()->get_region_color();
+               return UINT_INTERPOLATE (RGBA_TO_UINT(
+                                                SCALE_USHORT_TO_UINT8_T(color.get_red()),
+                                                SCALE_USHORT_TO_UINT8_T(color.get_green()),
+                                                SCALE_USHORT_TO_UINT8_T(color.get_blue()),
+                                                opacity), 
+                                        ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get(), 0.5);
+       }
+
+       case ChannelColors:
+               return UINT_INTERPOLATE (UINT_RGBA_CHANGE_A (NoteBase::midi_channel_colors[_note->channel()],
+                                                            opacity), 
+                                        ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get(), 0.5);
+
+       default:
+               return meter_style_fill_color(_note->velocity(), selected());
+       };
+
+       return 0;
+}
+
+void
+NoteBase::set_mouse_fractions (GdkEvent* ev)
+{
+       double ix, iy;
+       bool set_cursor = false;
+
+       switch (ev->type) {
+       case GDK_MOTION_NOTIFY:
+               ix = ev->motion.x;
+               iy = ev->motion.y;
+               set_cursor = true;
+               break;
+       case GDK_ENTER_NOTIFY:
+               ix = ev->crossing.x;
+               iy = ev->crossing.y;
+               set_cursor = true;
+               break;
+       case GDK_BUTTON_PRESS:
+       case GDK_BUTTON_RELEASE:
+               ix = ev->button.x;
+               iy = ev->button.y;
+               break;
+       default:
+               _mouse_x_fraction = -1.0;
+               _mouse_y_fraction = -1.0;
+               return;
+       }
+
+       boost::optional<Rect> bbox = _item->bounding_box ();
+       assert (bbox);
+
+       _item->canvas_to_item (ix, iy);
+       /* XXX: CANVAS */
+       /* hmm, something wrong here. w2i should give item-local coordinates
+          but it doesn't. for now, finesse this.
+       */
+       ix = ix - bbox.get().x0;
+       iy = iy - bbox.get().y0;
+
+       /* fraction of width/height */
+       double xf;
+       double yf;
+       bool notify = false;
+
+       xf = ix / bbox.get().width ();
+       yf = iy / bbox.get().height ();
+
+       if (xf != _mouse_x_fraction || yf != _mouse_y_fraction) {
+               notify = true;
+       }
+
+       _mouse_x_fraction = xf;
+       _mouse_y_fraction = yf;
+
+       if (notify) {
+                if (big_enough_to_trim()) {
+                        _region.note_mouse_position (_mouse_x_fraction, _mouse_y_fraction, set_cursor);
+                } else {
+                        /* pretend the mouse is in the middle, because this is not big enough
+                           to trim right now.
+                        */
+                        _region.note_mouse_position (0.5, 0.5, set_cursor);
+                }
+       }
+}
+
+bool
+NoteBase::event_handler (GdkEvent* ev)
+{
+       if (!_region.get_time_axis_view().editor().internal_editing()) {
+               return false;
+       }
+
+       switch (ev->type) {
+       case GDK_ENTER_NOTIFY:
+               set_mouse_fractions (ev);
+               _region.note_entered (this);
+               break;
+
+       case GDK_LEAVE_NOTIFY:
+               set_mouse_fractions (ev);
+               _region.note_left (this);
+               break;
+
+       case GDK_MOTION_NOTIFY:
+               set_mouse_fractions (ev);
+               break;
+
+       case GDK_BUTTON_PRESS:
+               set_mouse_fractions (ev);
+               if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state) && _selected) {
+                       show_channel_selector();
+                       return true;
+               }
+               break;
+
+       case GDK_BUTTON_RELEASE:
+               set_mouse_fractions (ev);
+               if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) {
+                       return true;
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       return _region.get_time_axis_view().editor().canvas_note_event (ev, _item);
+}
+
+bool
+NoteBase::mouse_near_ends () const
+{
+       return (_mouse_x_fraction >= 0.0 && _mouse_x_fraction < 0.25) ||
+               (_mouse_x_fraction >= 0.75 && _mouse_x_fraction < 1.0);
+}
+
+bool
+NoteBase::big_enough_to_trim () const
+{
+        return (x1() - x0()) > 10;
+}
+
diff --git a/gtk2_ardour/note_base.h b/gtk2_ardour/note_base.h
new file mode 100644 (file)
index 0000000..9680091
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+    Copyright (C) 2007 Paul Davis
+    Author: David Robillard
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __gtk_ardour_note_base_h__
+#define __gtk_ardour_note_base_h__
+
+#include <boost/shared_ptr.hpp>
+#include "canvas/types.h"
+#include "ardour/midi_model.h"
+
+#include "rgb_macros.h"
+#include "ardour_ui.h"
+#include "ui_config.h"
+
+class Editor;
+class MidiRegionView;
+
+namespace Evoral {
+       template<typename T> class Note;
+}
+
+namespace ArdourCanvas {
+       class Item;
+       class Text;
+}
+
+/** This manages all the event handling for any MIDI event on the canvas.
+ *
+ * This is not actually a canvas item itself to avoid the dreaded diamond,
+ * since various types of canvas items (Note (rect), Hit (diamond), etc)
+ * need to share this functionality but can't share an ancestor.
+ *
+ * Note: Because of this, derived classes need to manually bounce events to
+ * on_event, it won't happen automatically.
+ *
+ * A newer, better canvas should remove the need for all the ugly here.
+ */
+class NoteBase : public sigc::trackable
+{
+public:
+       typedef Evoral::Note<ARDOUR::MidiModel::TimeType> NoteType;
+
+       NoteBase (
+               MidiRegionView&                   region,
+               bool,
+               const boost::shared_ptr<NoteType> note = boost::shared_ptr<NoteType>()
+               );
+
+       virtual ~NoteBase ();
+
+       void set_item (ArdourCanvas::Item *);
+
+        static PBD::Signal1<void, NoteBase*> NoteBaseDeleted;
+
+       virtual void show() = 0;
+       virtual void hide() = 0;
+
+       bool valid() const { return _valid; }
+       void invalidate ();
+       void validate ();
+
+       bool selected() const { return _selected; }
+       void set_selected(bool yn);
+
+       virtual void move_event(double dx, double dy) = 0;
+
+       uint32_t base_color();
+
+       void show_velocity();
+       void hide_velocity();
+
+       /** Channel changed for this specific event */
+       void on_channel_change(uint8_t channel);
+
+       /** Channel selection changed */
+       void on_channel_selection_change(uint16_t selection);
+
+       void show_channel_selector();
+       void hide_channel_selector();
+
+       virtual void set_outline_color(uint32_t c) = 0;
+       virtual void set_fill_color(uint32_t c) = 0;
+
+       virtual ArdourCanvas::Coord x0 () const = 0;
+       virtual ArdourCanvas::Coord y0 () const = 0;
+       virtual ArdourCanvas::Coord x1 () const = 0;
+       virtual ArdourCanvas::Coord y1 () const = 0;
+
+        float mouse_x_fraction() const { return _mouse_x_fraction; }
+        float mouse_y_fraction() const { return _mouse_y_fraction; }
+
+       const boost::shared_ptr<NoteType> note() const { return _note; }
+       MidiRegionView& region_view() const { return _region; }
+
+       inline static uint32_t meter_style_fill_color(uint8_t vel, bool selected) {
+                if (selected) {
+                        if (vel < 64) {
+                                return UINT_INTERPOLATE(
+                                       ARDOUR_UI::config()->canvasvar_SelectedMidiNoteColorBase.get(),
+                                       ARDOUR_UI::config()->canvasvar_SelectedMidiNoteColorMid.get(),
+                                       (vel / (double)63.0));
+                        } else {
+                                return UINT_INTERPOLATE(
+                                       ARDOUR_UI::config()->canvasvar_SelectedMidiNoteColorMid.get(),
+                                       ARDOUR_UI::config()->canvasvar_SelectedMidiNoteColorTop.get(),
+                                       ((vel-64) / (double)63.0));
+                        }
+                } else {
+                        if (vel < 64) {
+                                return UINT_INTERPOLATE(
+                                       ARDOUR_UI::config()->canvasvar_MidiNoteColorBase.get(),
+                                       ARDOUR_UI::config()->canvasvar_MidiNoteColorMid.get(),
+                                       (vel / (double)63.0));
+                        } else {
+                                return UINT_INTERPOLATE(
+                                       ARDOUR_UI::config()->canvasvar_MidiNoteColorMid.get(),
+                                       ARDOUR_UI::config()->canvasvar_MidiNoteColorTop.get(),
+                                       ((vel-64) / (double)63.0));
+                        }
+                }
+       }
+
+       /// calculate outline colors from fill colors of notes
+       inline static uint32_t calculate_outline(uint32_t color) {
+               return UINT_INTERPOLATE(color, 0x000000ff, 0.5);
+       }
+
+       /// hue circle divided into 16 equal-looking parts, courtesy Thorsten Wilms
+       static const uint32_t midi_channel_colors[16];
+
+        bool mouse_near_ends () const;
+        bool big_enough_to_trim () const;
+
+protected:
+       enum State { None, Pressed, Dragging };
+
+       MidiRegionView&                   _region;
+       ArdourCanvas::Item*               _item;
+       ArdourCanvas::Text*               _text;
+//     Widget*                           _channel_selector_widget;
+       State                             _state;
+       const boost::shared_ptr<NoteType> _note;
+       bool                              _with_events;
+       bool                              _own_note;
+       bool                              _selected;
+       bool                              _valid;
+        float                             _mouse_x_fraction;
+        float                             _mouse_y_fraction;
+        
+        void set_mouse_fractions (GdkEvent*);
+
+private:
+       bool event_handler (GdkEvent *);
+};
+
+#endif /* __gtk_ardour_note_h__ */
index 09449c56302f825c71caff51b21eb9fa7ed701a4..7c5fcfbf6e92fdd5a3498dd0e03b3c2b418a8869 100644 (file)
@@ -28,7 +28,6 @@
 
 NSM_Client::NSM_Client()
 {
-    _session_loaded = false;
 }
 
 int
@@ -59,9 +58,3 @@ NSM_Client::command_open(const char *name,
     }
     return r;
 }
-
-void
-NSM_Client::command_session_is_loaded ( void )
-{
-    _session_loaded = true;
-}
index a2b0c111518a803441fd931d3f1c98a4debcd52d..5491e1985febc860e51d8f50a7a2e9488a4a4fc1 100644 (file)
@@ -28,17 +28,12 @@ class NSM_Client:public NSM::Client
         NSM_Client();
         ~NSM_Client() { }
 
-        bool session_loaded(void) { return _session_loaded; }
-
     protected:
 
-        bool _session_loaded;
-
         int command_open(const char *name,
                          const char *display_name,
                          const char *client_id,
                          char **out_msg);
         int command_save(char **out_msg);
-        void command_session_is_loaded (void);
 };
 
index c3de82daabe7e0c600c8e71da0e1368d2da7251a..7700ae5839b5dcb8902a10acf7b5eaf088bf291f 100644 (file)
@@ -295,6 +295,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
        virtual void queue_visual_videotimeline_update () = 0;
        virtual void toggle_ruler_video (bool) = 0;
        virtual void toggle_xjadeo_proc (int) = 0;
+       virtual void toggle_xjadeo_viewoption (int, int) = 0;
        virtual void set_xjadeo_sensitive (bool onoff) = 0;
        virtual int  get_videotl_bar_height () const = 0;
        virtual void set_video_timeline_height (const int h) = 0;
index bad603b03038039870bfad0f66ea70794223507e..5a59b5ce5dfc3979e6e06c37e2387626e52f8a83 100644 (file)
@@ -345,7 +345,7 @@ RhythmFerret::do_split_action ()
           performed on the selection only (without entered_regionview or the edit point
           being considered)
        */
-       RegionSelection regions = editor.get_regions_from_selection();
+       RegionSelection regions = editor.selection->regions;
 
        if (regions.empty()) {
                return;
index 35d306cc64ce70d5555a9333bbe6f418452066a5..2d83dbd4e765b3720d0387d35ab842737f9114c1 100644 (file)
@@ -243,7 +243,7 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
 
        route_group_menu = new RouteGroupMenu (_session, plist);
 
-       // gm.get_gain_slider().signal_scroll_event().connect(sigc::mem_fun(*this, &RouteTimeAxisView::controls_ebox_scroll), false);
+       gm.get_gain_slider().signal_scroll_event().connect(sigc::mem_fun(*this, &RouteTimeAxisView::controls_ebox_scroll), false);
 
        gm.get_level_meter().signal_scroll_event().connect (sigc::mem_fun (*this, &RouteTimeAxisView::controls_ebox_scroll), false);
 }
diff --git a/gtk2_ardour/sys_ex.cc b/gtk2_ardour/sys_ex.cc
new file mode 100644 (file)
index 0000000..94ee530
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+    Copyright (C) 2009 Paul Davis
+    Author: Hans Baier
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <iostream>
+#include "canvas/flag.h"
+#include "ardour_ui.h"
+#include "sys_ex.h"
+
+using namespace std;
+
+SysEx::SysEx (
+       MidiRegionView& region,
+       ArdourCanvas::Group* parent,
+       string&         text,
+       double          height,
+       double          x,
+       double          y)
+       : _region (region)
+{
+       _flag = new ArdourCanvas::Flag (
+               parent,
+               height, 
+               ARDOUR_UI::config()->canvasvar_MidiSysExOutline.get(),
+               ARDOUR_UI::config()->canvasvar_MidiSysExFill.get(),
+               ArdourCanvas::Duple (x, y)
+               );
+       
+       _flag->set_text (text);
+}
+
+SysEx::~SysEx()
+{
+}
+
+bool
+SysEx::event_handler (GdkEvent* ev)
+{
+       switch (ev->type) {
+       case GDK_BUTTON_PRESS:
+               if (ev->button.button == 3) {
+                       return true;
+               }
+               break;
+
+       case GDK_SCROLL:
+               if (ev->scroll.direction == GDK_SCROLL_UP) {
+                       return true;
+               } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
+                       return true;
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       return false;
+}
+
+void
+SysEx::hide ()
+{
+       _flag->hide ();
+}
+
+void
+SysEx::show ()
+{
+       _flag->show ();
+}
diff --git a/gtk2_ardour/sys_ex.h b/gtk2_ardour/sys_ex.h
new file mode 100644 (file)
index 0000000..1d6787a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright (C) 2009 Paul Davis
+    Author: Hans Baier
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __SYSEX_H__
+#define __SYSEX_H__
+
+class MidiRegionView;
+
+namespace ArdourCanvas {
+       class Flag;
+}
+
+class SysEx
+{
+public:
+       SysEx (
+                       MidiRegionView& region,
+                       ArdourCanvas::Group* parent,
+                       std::string&    text,
+                       double          height,
+                       double          x,
+                       double          y);
+
+       ~SysEx ();
+
+       void hide ();
+       void show ();
+
+        ArdourCanvas::Item& item() const { return *_flag; }
+
+private:       
+       bool event_handler (GdkEvent* ev);
+
+       MidiRegionView& _region;
+       ArdourCanvas::Flag* _flag;
+};
+
+#endif /* __SYSEX_H__ */
index 00b212710e63392a610d702523b9eac09c0fc83f..3af660ef77b60889f362796664bd133099f89a12 100644 (file)
@@ -418,7 +418,7 @@ SystemExec::terminate ()
        if (pid) {
                ::fprintf(stderr, "Child process is running. trying SIGTERM\n");
                ::kill(pid, SIGTERM);
-               ::usleep(10000);
+               ::usleep(50000);
                wait(WNOHANG);
        }
        if (pid) {
index 7780c4f02bfa91e6d30e7e19848fffda6663309e..854b7def2228c53da3e9c3e0227ac15190803d76 100644 (file)
@@ -464,7 +464,7 @@ TranscodeFfmpeg::transcode (std::string outfile, const int outw, const int outh,
        argp[6] = (char*) calloc(10,sizeof(char)); snprintf(argp[6], 10, "%ix%i", width, height);
        argp[7] = strdup("-y");
        argp[8] = strdup("-vcodec");
-       argp[9] = strdup("mjpeg");
+       argp[9] = strdup("mpeg4");
        argp[10] = strdup("-an");
        argp[11] = strdup("-intra");
        argp[12] = strdup("-g");
index f29712e326a570bd9a9ba6d570a80b1ec87c5c26..5bc6bb67771439c59c7f42dd03bdd50b9540953e 100644 (file)
@@ -39,10 +39,14 @@ VideoMonitor::VideoMonitor (PublicEditor *ed, std::string xjadeo_bin_path)
        sync_by_manual_seek = false;
        _restore_settings_mask = 0;
        clock_connection = sigc::connection();
+       state_connection = sigc::connection();
        debug_enable = false;
+       state_clk_divide = 0;
+       starting = 0;
+       osdmode = 10; // 1: frameno, 2: timecode, 8: box
 
        process = new SystemExec(xjadeo_bin_path, X_("-R"));
-       process->ReadStdout.connect (*this, invalidator (*this), boost::bind (&VideoMonitor::parse_output, this, _1 ,_2), gui_context());
+       process->ReadStdout.connect_same_thread (*this, boost::bind (&VideoMonitor::parse_output, this, _1 ,_2));
        process->Terminated.connect (*this, invalidator (*this), boost::bind (&VideoMonitor::terminated, this), gui_context());
 }
 
@@ -51,6 +55,9 @@ VideoMonitor::~VideoMonitor ()
        if (clock_connection.connected()) {
                clock_connection.disconnect();
        }
+       if (state_connection.connected()) {
+               state_connection.disconnect();
+       }
        delete process;
 }
 
@@ -75,6 +82,8 @@ void
 VideoMonitor::quit ()
 {
        if (!is_started()) return;
+       if (state_connection.connected()) { state_connection.disconnect(); }
+       if (clock_connection.connected()) { clock_connection.disconnect(); }
        process->write_to_stdin("get windowsize\n");
        process->write_to_stdin("get windowpos\n");
        process->write_to_stdin("get letterbox\n");
@@ -92,13 +101,14 @@ VideoMonitor::quit ()
        int timeout = 40;
        while (is_started() && --timeout) {
                usleep(50000);
+               sched_yield();
        }
-       if (timeout == 0) {
+       if (timeout <= 0) {
                printf("xjadeo connection: time-out. session may not be saved.\n");
+               process->terminate();
        }
 #endif
-       process->terminate();
-       if (clock_connection.connected()) { clock_connection.disconnect(); }
+       save_session();
 }
 
 void
@@ -106,7 +116,9 @@ VideoMonitor::open (std::string filename)
 {
        if (!is_started()) return;
        manually_seeked_frame = 0;
+       osdmode = 10; // 1: frameno, 2: timecode, 8: box
        sync_by_manual_seek = false;
+       starting = 15;
        process->write_to_stdin("load " + filename + "\n");
        process->write_to_stdin("set fps -1\n");
        process->write_to_stdin("window resize 100%\n");
@@ -119,9 +131,29 @@ VideoMonitor::open (std::string filename)
                if (skip_setting(it->first)) { continue; }
                process->write_to_stdin(it->first + " " + it->second + "\n");
        }
+       if (!state_connection.connected()) {
+               starting = 15;
+               querystate();
+               state_clk_divide = 0;
+               /* TODO once every two second or so -- state_clk_divide hack below */
+               state_connection = ARDOUR_UI::RapidScreenUpdate.connect (sigc::mem_fun (*this, &VideoMonitor::querystate));
+       }
        xjadeo_sync_setup();
 }
 
+void
+VideoMonitor::querystate ()
+{
+       /* clock-divider hack -- RapidScreenUpdate == every_point_one_seconds */
+       state_clk_divide = (state_clk_divide + 1) % 15; // every 1.5 seconds
+       if (state_clk_divide != 0) return;
+
+       process->write_to_stdin("get fullscreen\n");
+       process->write_to_stdin("get ontop\n");
+       process->write_to_stdin("get osdcfg\n");
+       process->write_to_stdin("get letterbox\n");
+}
+
 bool
 VideoMonitor::skip_setting (std::string which)
 {
@@ -136,6 +168,51 @@ VideoMonitor::skip_setting (std::string which)
        return false;
 }
 
+void
+VideoMonitor::send_cmd (int what, int param)
+{
+       bool osd_update = false;
+       if (!is_started()) return;
+       switch (what) {
+               case 1:
+                       if (param) process->write_to_stdin("window ontop on\n");
+                       else process->write_to_stdin("window ontop off\n");
+                       break;
+               case 2:
+                       if (param) osdmode |= 2;
+                       else osdmode &= ~2;
+                       osd_update = true;
+                       break;
+               case 3:
+                       if (param) osdmode |= 1;
+                       else osdmode &= ~1;
+                       osd_update = true;
+                       break;
+               case 4:
+                       if (param) osdmode |= 8;
+                       else osdmode &= ~8;
+                       osd_update = true;
+                       break;
+               case 5:
+                       if (param) process->write_to_stdin("window zoom on\n");
+                       else process->write_to_stdin("window zoom off\n");
+                       break;
+               case 6:
+                       if (param) process->write_to_stdin("window letterbox on\n");
+                       else process->write_to_stdin("window letterbox off\n");
+                       break;
+               case 7:
+                       process->write_to_stdin("window resize 100%");
+                       break;
+               default:
+                       break;
+       }
+       if (osd_update >= 0) {
+               std::ostringstream osstream; osstream << "osd mode " << osdmode << "\n";
+               process->write_to_stdin(osstream.str());
+       }
+}
+
 bool
 VideoMonitor::is_started ()
 {
@@ -196,12 +273,37 @@ VideoMonitor::parse_output (std::string d, size_t s)
                                        } else if(key ==  "windowsize") {
                                                xjadeo_settings["window size"] = value;
                                        } else if(key ==  "windowontop") {
+                                               if (starting || xjadeo_settings["window ontop"] != value) {
+                                                       starting &= ~2;
+                                                       if (atoi(value.c_str())) { UiState("xjadeo-window-ontop-on"); }
+                                                       else { UiState("xjadeo-window-ontop-off"); }
+                                               }
                                                xjadeo_settings["window ontop"] = value;
                                        } else if(key ==  "fullscreen") {
+                                               if (starting || xjadeo_settings["window zoom"] != value) {
+                                                       starting &= ~4;
+                                                       if (atoi(value.c_str())) { UiState("xjadeo-window-fullscreen-on"); }
+                                                       else { UiState("xjadeo-window-fullscreen-off"); }
+                                               }
                                                xjadeo_settings["window zoom"] = value;
                                        } else if(key ==  "letterbox") {
+                                               if (starting || xjadeo_settings["window letterbox"] != value) {
+                                                       starting &= ~8;
+                                                       if (atoi(value.c_str())) { UiState("xjadeo-window-letterbox-on"); }
+                                                       else { UiState("xjadeo-window-letterbox-off"); }
+                                               }
                                                xjadeo_settings["window letterbox"] = value;
                                        } else if(key ==  "osdmode") {
+                                               if (starting || xjadeo_settings["osd mode"] != value) {
+                                                       starting &= ~1;
+                                                       osdmode = atoi(value.c_str());
+                                                       if ((osdmode & 1) == 1) { UiState("xjadeo-window-osd-frame-on"); }
+                                                       if ((osdmode & 1) == 0) { UiState("xjadeo-window-osd-frame-off"); }
+                                                       if ((osdmode & 2) == 2) { UiState("xjadeo-window-osd-timecode-on"); }
+                                                       if ((osdmode & 2) == 0) { UiState("xjadeo-window-osd-timecode-off"); }
+                                                       if ((osdmode & 8) == 8) { UiState("xjadeo-window-osd-box-on"); }
+                                                       if ((osdmode & 8) == 0) { UiState("xjadeo-window-osd-box-off"); }
+                                               }
                                                xjadeo_settings["osd mode"] = value;
                                        } else if(key ==  "offset") {
                                                xjadeo_settings["set offset"] = value;
@@ -218,6 +320,7 @@ VideoMonitor::parse_output (std::string d, size_t s)
 void
 VideoMonitor::terminated ()
 {
+       process->terminate(); // from gui-context clean up
        save_session();
        Terminated();
 }
@@ -298,6 +401,7 @@ VideoMonitor::get_custom_setting (const std::string k)
 {
        return (xjadeo_settings[k]);
 }
+
 #define NO_OFFSET (1<<31) //< skip setting or modifying offset --  TODO check ARDOUR::frameoffset_t max value.
 void
 VideoMonitor::srsupdate ()
index 7bb74c7e05561262ff48cb65108f92eda96521ab..be3b76f9a47340741355275d356893c09c8e98e1 100644 (file)
@@ -71,9 +71,12 @@ class VideoMonitor : public sigc::trackable , public ARDOUR::SessionHandlePtr, p
        void set_offset (ARDOUR::frameoffset_t);
        void manual_seek (ARDOUR::framepos_t, bool, ARDOUR::frameoffset_t);
        void srsupdate ();
+       void querystate ();
        bool synced_by_manual_seeks() { return sync_by_manual_seek; }
 
        sigc::signal<void> Terminated;
+       PBD::Signal1<void,std::string> UiState;
+       void send_cmd (int what, int param);
 
 #if 1
        void set_debug (bool onoff) { debug_enable = onoff; }
@@ -99,6 +102,10 @@ class VideoMonitor : public sigc::trackable , public ARDOUR::SessionHandlePtr, p
        ARDOUR::framepos_t manually_seeked_frame;
        bool sync_by_manual_seek;
        sigc::connection clock_connection;
+       sigc::connection state_connection;
+       int state_clk_divide;
+       int starting;
+       int osdmode;
 #if 1
        bool debug_enable;
 #endif
index dd47a829709256b208a4185e7641af44f9524198..9cd9d35315790f7dc48526d0d2cabac6da40da8b 100644 (file)
@@ -155,8 +155,8 @@ VideoTimeLine::close_session ()
        if (video_duration == 0) {
                return;
        }
-       close_video_monitor();
        save_session();
+       close_video_monitor();
 
        remove_frames();
        video_filename = "";
@@ -581,6 +581,30 @@ VideoTimeLine::gui_update(std::string const & t) {
                editor->toggle_xjadeo_proc(0);
                //close_video_monitor();
                editor->set_xjadeo_sensitive(false);
+       } else if (t == "xjadeo-window-ontop-on") {
+               editor->toggle_xjadeo_viewoption(1, 1);
+       } else if (t == "xjadeo-window-ontop-off") {
+               editor->toggle_xjadeo_viewoption(1, 0);
+       } else if (t == "xjadeo-window-osd-timecode-on") {
+               editor->toggle_xjadeo_viewoption(2, 1);
+       } else if (t == "xjadeo-window-osd-timecode-off") {
+               editor->toggle_xjadeo_viewoption(2, 0);
+       } else if (t == "xjadeo-window-osd-frame-on") {
+               editor->toggle_xjadeo_viewoption(3, 1);
+       } else if (t == "xjadeo-window-osd-frame-off") {
+               editor->toggle_xjadeo_viewoption(3, 0);
+       } else if (t == "xjadeo-window-osd-box-on") {
+               editor->toggle_xjadeo_viewoption(4, 1);
+       } else if (t == "xjadeo-window-osd-box-off") {
+               editor->toggle_xjadeo_viewoption(4, 0);
+       } else if (t == "xjadeo-window-fullscreen-on") {
+               editor->toggle_xjadeo_viewoption(5, 1);
+       } else if (t == "xjadeo-window-fullscreen-off") {
+               editor->toggle_xjadeo_viewoption(5, 0);
+       } else if (t == "xjadeo-window-letterbox-on") {
+               editor->toggle_xjadeo_viewoption(6, 1);
+       } else if (t == "xjadeo-window-letterbox-off") {
+               editor->toggle_xjadeo_viewoption(6, 0);
        }
 }
 
@@ -688,6 +712,7 @@ VideoTimeLine::open_video_monitor() {
                vmonitor = new VideoMonitor(editor, _xjadeo_bin);
                vmonitor->set_session(_session);
                vmonitor->Terminated.connect (sigc::mem_fun (*this, &VideoTimeLine::terminated_video_monitor));
+               vmonitor->UiState.connect (*this, invalidator (*this), boost::bind (&VideoTimeLine::gui_update, this, _1), gui_context());
        } else if (vmonitor->is_started()) {
                return;
        }
@@ -723,6 +748,15 @@ VideoTimeLine::close_video_monitor() {
        }
 }
 
+void
+VideoTimeLine::control_video_monitor(int what, int param) {
+       if (!vmonitor || !vmonitor->is_started()) {
+               return;
+       }
+       vmonitor->send_cmd(what, param);
+}
+
+
 void
 VideoTimeLine::terminated_video_monitor () {
        if (vmonitor) {
index ef889af452d140b9fa23866dd5a81506942797ce..ab1a9a92d85e0b85799edc0116ec7974ee742cf1 100644 (file)
@@ -78,6 +78,7 @@ class VideoTimeLine : public sigc::trackable, public ARDOUR::SessionHandlePtr, p
 
        void open_video_monitor ();
        void close_video_monitor ();
+       void control_video_monitor (int, int);
        void terminated_video_monitor ();
        void manual_seek_video_monitor (framepos_t pos);
 
index 53dd18638410ea761c945ec9d5cd3a0a0553205e..6f54d17d02a21f32dd520b29547dd1a408b858b0 100644 (file)
@@ -43,7 +43,7 @@ using namespace PBD;
 
 MIDIClock_Slave::MIDIClock_Slave (Session& s, MIDI::Port& p, int ppqn)
        : ppqn (ppqn)
-       , bandwidth (1.0 / 60.0) // 1 BpM = 1 / 60 Hz
+       , bandwidth (10.0 / 60.0) // 1 BpM = 1 / 60 Hz
 {
        session = (ISlaveSessionProxy *) new SlaveSessionProxy(s);
        rebind (p);
@@ -53,7 +53,7 @@ MIDIClock_Slave::MIDIClock_Slave (Session& s, MIDI::Port& p, int ppqn)
 MIDIClock_Slave::MIDIClock_Slave (ISlaveSessionProxy* session_proxy, int ppqn)
        : session(session_proxy)
        , ppqn (ppqn)
-       , bandwidth (1.0 / 60.0) // 1 BpM = 1 / 60 Hz
+       , bandwidth (10.0 / 60.0) // 1 BpM = 1 / 60 Hz
 {
        reset ();
 }
@@ -149,11 +149,12 @@ MIDIClock_Slave::update_midi_clock (Parser& /*parser*/, framepos_t timestamp)
                calculate_filter_coefficients();
 
                // calculate loop error
-               // we use session->audible_frame() instead of t1 here
+               // we use session->transport_frame() instead of t1 here
                // because t1 is used to calculate the transport speed,
                // so the loop will compensate for accumulating rounding errors
-               error = (double(should_be_position) - double(session->audible_frame()));
+               error = (double(should_be_position) - double(session->transport_frame()));
                e = error / double(session->frame_rate());
+               current_delta = error;
 
                // update DLL
                t0 = t1;
@@ -328,8 +329,8 @@ MIDIClock_Slave::speed_and_position (double& speed, framepos_t& pos)
        // calculate speed
        speed = ((t1 - t0) * session->frame_rate()) / one_ppqn_in_frames;
 
-       // provide a 3% deadzone to lock the speed
-       if (fabs(speed - 1.0) <= 0.03)
+       // provide a 0.1% deadzone to lock the speed
+       if (fabs(speed - 1.0) <= 0.001)
                speed = 1.0;
 
        // calculate position
@@ -344,7 +345,6 @@ MIDIClock_Slave::speed_and_position (double& speed, framepos_t& pos)
        }
 
        DEBUG_TRACE (DEBUG::MidiClock, string_compose ("speed_and_position: %1 & %2 <-> %3 (transport)\n", speed, pos, session->transport_frame()));
-       current_delta = pos - session->transport_frame();
 
        return true;
 }
index cd7daaf185f8df9975b759951fee7718dd1f565f..7ed8030e6bd7574aa86263230732119f4c2026d8 100644 (file)
@@ -515,7 +515,9 @@ Session::follow_slave (pframes_t nframes)
                slave_speed = 0.0f;
        }
 
-       if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) {
+       if (_slave->is_always_synced() ||
+                       (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
+                       ) {
 
                /* if the TC source is synced, then we assume that its
                   speed is binary: 0.0 or 1.0
@@ -543,7 +545,9 @@ Session::follow_slave (pframes_t nframes)
                                                   _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
 
 
-       if (_slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) {
+       if (_slave_state == Running && !_slave->is_always_synced() &&
+                       !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
+                       ) {
 
                if (_transport_speed != 0.0f) {
 
diff --git a/libs/canvas/canvas/fwd.h b/libs/canvas/canvas/fwd.h
new file mode 100644 (file)
index 0000000..14847fa
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+    Copyright (C) 2011 Paul Davis
+    Author: Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __canvas_canvas_fwd_h__
+#define __canvas_canvas_fwd_h__
+
+namespace ArdourCanvas {
+       class WaveView;
+       class Line;
+       class Rectangle;
+       class Polygon;
+       class PolyLine;
+       class GtkCanvas;
+       class GtkCanvasViewport;
+       class Text;
+}
+
+#endif /* __canvas_canvas_fwd_h__ */
index 26bef20232a04a1ce5af757d8c9c312c887a0861..e2e92385aaf1f18446d435fe548aec22c30ef19a 100644 (file)
@@ -142,7 +142,7 @@ public:
                typedef const Note<Time>* value_type;
                inline bool operator()(const boost::shared_ptr< const Note<Time> > a,
                                       const boost::shared_ptr< const Note<Time> > b) const {
-                       return musical_time_less_than (a->end_time(), b->end_time());
+                       return musical_time_greater_than (a->end_time(), b->end_time());
                }
        };