summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-04-05 17:16:33 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-04-05 17:16:33 -0400
commit8eef4b1904bcc611f5f4230927ca9eda2352d36b (patch)
treee004392027fb0208091ffb60baaa597a6d4a95b8
parent07a505b1b271f64a1ffb2da32da0548d32cd13de (diff)
master merge; new files not added after initial cairocanvas patch application
-rw-r--r--doc/region_ops.txt5
-rw-r--r--gtk2_ardour/ardour.menus.in11
-rw-r--r--gtk2_ardour/ardour_ui.cc26
-rw-r--r--gtk2_ardour/editor.cc85
-rw-r--r--gtk2_ardour/editor.h10
-rw-r--r--gtk2_ardour/editor_actions.cc113
-rw-r--r--gtk2_ardour/editor_ops.cc2
-rw-r--r--gtk2_ardour/editor_videotimeline.cc25
-rw-r--r--gtk2_ardour/export_video_dialog.cc169
-rw-r--r--gtk2_ardour/export_video_dialog.h7
-rw-r--r--gtk2_ardour/hit.cc114
-rw-r--r--gtk2_ardour/hit.h63
-rw-r--r--gtk2_ardour/note_base.cc376
-rw-r--r--gtk2_ardour/note_base.h172
-rw-r--r--gtk2_ardour/nsm.cc7
-rw-r--r--gtk2_ardour/nsm.h5
-rw-r--r--gtk2_ardour/public_editor.h1
-rw-r--r--gtk2_ardour/rhythm_ferret.cc2
-rw-r--r--gtk2_ardour/route_time_axis.cc2
-rw-r--r--gtk2_ardour/sys_ex.cc86
-rw-r--r--gtk2_ardour/sys_ex.h54
-rw-r--r--gtk2_ardour/system_exec.cc2
-rw-r--r--gtk2_ardour/transcode_ffmpeg.cc2
-rw-r--r--gtk2_ardour/video_monitor.cc112
-rw-r--r--gtk2_ardour/video_monitor.h7
-rw-r--r--gtk2_ardour/video_timeline.cc36
-rw-r--r--gtk2_ardour/video_timeline.h1
-rw-r--r--libs/ardour/midi_clock_slave.cc14
-rw-r--r--libs/ardour/session_process.cc8
-rw-r--r--libs/canvas/canvas/fwd.h35
-rw-r--r--libs/evoral/evoral/Sequence.hpp2
31 files changed, 1366 insertions, 188 deletions
diff --git a/doc/region_ops.txt b/doc/region_ops.txt
index 69851bf3eb..c6b4ab00e5 100644
--- a/doc/region_ops.txt
+++ b/doc/region_ops.txt
@@ -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.
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index 608f4dd6e4..e50f62cfbb 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -440,6 +440,17 @@
#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">
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 4c1be5f674..1022acee2d 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -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 ()) {
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index bde5b65893..194c344241 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -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
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 3adcfc8ab4..43d3fccedf 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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 ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 0fe99582ca..1efc358513 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -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
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 7fed4fc410..9eb0a4c2bd 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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()) {
diff --git a/gtk2_ardour/editor_videotimeline.cc b/gtk2_ardour/editor_videotimeline.cc
index a58a896fdd..564e3016e7 100644
--- a/gtk2_ardour/editor_videotimeline.cc
+++ b/gtk2_ardour/editor_videotimeline.cc
@@ -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
diff --git a/gtk2_ardour/export_video_dialog.cc b/gtk2_ardour/export_video_dialog.cc
index 380b8240f7..03b64cfbe3 100644
--- a/gtk2_ardour/export_video_dialog.cc
+++ b/gtk2_ardour/export_video_dialog.cc
@@ -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();
}
}
diff --git a/gtk2_ardour/export_video_dialog.h b/gtk2_ardour/export_video_dialog.h
index ae0beafd37..72376512d1 100644
--- a/gtk2_ardour/export_video_dialog.h
+++ b/gtk2_ardour/export_video_dialog.h
@@ -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
index 0000000000..a7d1a9b47b
--- /dev/null
+++ b/gtk2_ardour/hit.cc
@@ -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
index 0000000000..3afdd91367
--- /dev/null
+++ b/gtk2_ardour/hit.h
@@ -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
index 0000000000..b8587e16da
--- /dev/null
+++ b/gtk2_ardour/note_base.cc
@@ -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
index 0000000000..9680091c75
--- /dev/null
+++ b/gtk2_ardour/note_base.h
@@ -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__ */
diff --git a/gtk2_ardour/nsm.cc b/gtk2_ardour/nsm.cc
index 09449c5630..7c5fcfbf6e 100644
--- a/gtk2_ardour/nsm.cc
+++ b/gtk2_ardour/nsm.cc
@@ -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;
-}
diff --git a/gtk2_ardour/nsm.h b/gtk2_ardour/nsm.h
index a2b0c11151..5491e1985f 100644
--- a/gtk2_ardour/nsm.h
+++ b/gtk2_ardour/nsm.h
@@ -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);
};
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index c3de82daab..7700ae5839 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -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;
diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc
index bad603b030..5a59b5ce5d 100644
--- a/gtk2_ardour/rhythm_ferret.cc
+++ b/gtk2_ardour/rhythm_ferret.cc
@@ -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;
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 35d306cc64..2d83dbd4e7 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -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
index 0000000000..94ee5302e3
--- /dev/null
+++ b/gtk2_ardour/sys_ex.cc
@@ -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
index 0000000000..1d6787a75e
--- /dev/null
+++ b/gtk2_ardour/sys_ex.h
@@ -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__ */
diff --git a/gtk2_ardour/system_exec.cc b/gtk2_ardour/system_exec.cc
index 00b212710e..3af660ef77 100644
--- a/gtk2_ardour/system_exec.cc
+++ b/gtk2_ardour/system_exec.cc
@@ -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) {
diff --git a/gtk2_ardour/transcode_ffmpeg.cc b/gtk2_ardour/transcode_ffmpeg.cc
index 7780c4f02b..854b7def22 100644
--- a/gtk2_ardour/transcode_ffmpeg.cc
+++ b/gtk2_ardour/transcode_ffmpeg.cc
@@ -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");
diff --git a/gtk2_ardour/video_monitor.cc b/gtk2_ardour/video_monitor.cc
index f29712e326..5bc6bb6777 100644
--- a/gtk2_ardour/video_monitor.cc
+++ b/gtk2_ardour/video_monitor.cc
@@ -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 ()
diff --git a/gtk2_ardour/video_monitor.h b/gtk2_ardour/video_monitor.h
index 7bb74c7e05..be3b76f9a4 100644
--- a/gtk2_ardour/video_monitor.h
+++ b/gtk2_ardour/video_monitor.h
@@ -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
diff --git a/gtk2_ardour/video_timeline.cc b/gtk2_ardour/video_timeline.cc
index dd47a82970..9cd9d35315 100644
--- a/gtk2_ardour/video_timeline.cc
+++ b/gtk2_ardour/video_timeline.cc
@@ -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;
}
@@ -724,6 +749,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) {
delete vmonitor;
diff --git a/gtk2_ardour/video_timeline.h b/gtk2_ardour/video_timeline.h
index ef889af452..ab1a9a92d8 100644
--- a/gtk2_ardour/video_timeline.h
+++ b/gtk2_ardour/video_timeline.h
@@ -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);
diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc
index 53dd186384..6f54d17d02 100644
--- a/libs/ardour/midi_clock_slave.cc
+++ b/libs/ardour/midi_clock_slave.cc
@@ -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;
}
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index cd7daaf185..7ed8030e6b 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -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
index 0000000000..14847fab54
--- /dev/null
+++ b/libs/canvas/canvas/fwd.h
@@ -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__ */
diff --git a/libs/evoral/evoral/Sequence.hpp b/libs/evoral/evoral/Sequence.hpp
index 26bef20232..e2e92385aa 100644
--- a/libs/evoral/evoral/Sequence.hpp
+++ b/libs/evoral/evoral/Sequence.hpp
@@ -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());
}
};