master merge; new files not added after initial cairocanvas patch application

This commit is contained in:
Paul Davis
2013-04-05 17:16:33 -04:00
parent 07a505b1b2
commit 8eef4b1904
31 changed files with 1367 additions and 189 deletions

View 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.

View File

@@ -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">

View 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 ()) {

View 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.
* region. In this case, use 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.
*
* 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 (!tracks_without_relevant_regions.empty()) {
/* there are some selected tracks with neither selected
* regions or their equivalents: act upon all regions in
* those tracks
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
*/
get_regions_at (regions, where, tracks_without_relevant_regions);
tracks = track_views;
}
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

View 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 ();

View 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

View 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()) {

View 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

View 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();
}
}

View 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;

114
gtk2_ardour/hit.cc Normal file
View File

@@ -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);
}

63
gtk2_ardour/hit.h Normal file
View File

@@ -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__ */

376
gtk2_ardour/note_base.cc Normal file
View File

@@ -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;
}

172
gtk2_ardour/note_base.h Normal file
View File

@@ -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__ */

View 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;
}

View 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);
};

View 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;

View 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;

View 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);
}

86
gtk2_ardour/sys_ex.cc Normal file
View File

@@ -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 ();
}

54
gtk2_ardour/sys_ex.h Normal file
View File

@@ -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__ */

View 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) {

View 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");

View 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 ()

View 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

View 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) {

View 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);

View 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;
}

View 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) {

35
libs/canvas/canvas/fwd.h Normal file
View File

@@ -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__ */

View 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());
}
};