another day or two's work on timeline type conversion
This commit is contained in:
parent
04e8dbb342
commit
9d69fa3820
|
@ -176,19 +176,21 @@ ARDOUR_UI::set_flat_buttons ()
|
|||
|
||||
|
||||
void
|
||||
ARDOUR_UI::update_transport_clocks (samplepos_t pos)
|
||||
ARDOUR_UI::update_transport_clocks (samplepos_t p)
|
||||
{
|
||||
timepos_t pos (p);
|
||||
|
||||
switch (UIConfiguration::instance().get_primary_clock_delta_mode()) {
|
||||
case NoDelta:
|
||||
primary_clock->set (pos);
|
||||
break;
|
||||
case DeltaEditPoint:
|
||||
primary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
|
||||
primary_clock->set (pos, false, timecnt_t (editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)));
|
||||
break;
|
||||
case DeltaOriginMarker:
|
||||
{
|
||||
Location* loc = _session->locations()->clock_origin_location ();
|
||||
primary_clock->set (pos, false, loc ? loc->start_sample() : 0);
|
||||
primary_clock->set (pos, false, timecnt_t (loc ? loc->start_sample() : 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -198,12 +200,12 @@ ARDOUR_UI::update_transport_clocks (samplepos_t pos)
|
|||
secondary_clock->set (pos);
|
||||
break;
|
||||
case DeltaEditPoint:
|
||||
secondary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
|
||||
secondary_clock->set (pos, false, timecnt_t (editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)));
|
||||
break;
|
||||
case DeltaOriginMarker:
|
||||
{
|
||||
Location* loc = _session->locations()->clock_origin_location ();
|
||||
secondary_clock->set (pos, false, loc ? loc->start_sample() : 0);
|
||||
secondary_clock->set (pos, false, timecnt_t (loc ? loc->start_sample() : 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -213,7 +215,7 @@ ARDOUR_UI::update_transport_clocks (samplepos_t pos)
|
|||
}
|
||||
|
||||
if (!editor->preview_video_drag_active ()) {
|
||||
ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(pos);
|
||||
ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "ardour/parameter_types.h"
|
||||
#include "ardour/tempo.h"
|
||||
|
||||
#include "temporal/range.h"
|
||||
|
||||
#include "evoral/Curve.h"
|
||||
|
||||
#include "canvas/debug.h"
|
||||
|
@ -78,7 +80,7 @@ using namespace Editing;
|
|||
|
||||
|
||||
#define TIME_TO_SAMPLES(x) (_distance_measure (x, Temporal::AudioTime))
|
||||
#define SAMPLES_TO_TIME(x) (_distance_measure (x, alist->time_style()))
|
||||
#define SAMPLES_TO_TIME(x) (_distance_measure (x, alist->time_domain()))
|
||||
|
||||
/** @param converter A TimeConverter whose origin_b is the start time of the AutomationList in session samples.
|
||||
* This will not be deleted by AutomationLine.
|
||||
|
@ -88,7 +90,7 @@ AutomationLine::AutomationLine (const string& name,
|
|||
ArdourCanvas::Item& parent,
|
||||
boost::shared_ptr<AutomationList> al,
|
||||
const ParameterDescriptor& desc,
|
||||
DistanceMeasure const & m)
|
||||
Temporal::DistanceMeasure const & m)
|
||||
: trackview (tv)
|
||||
, _name (name)
|
||||
, alist (al)
|
||||
|
@ -99,12 +101,6 @@ AutomationLine::AutomationLine (const string& name,
|
|||
, _desc (desc)
|
||||
, _distance_measure (m)
|
||||
{
|
||||
if (converter) {
|
||||
_our_time_converter = false;
|
||||
} else {
|
||||
_our_time_converter = true;
|
||||
}
|
||||
|
||||
_visible = Line;
|
||||
|
||||
update_pending = false;
|
||||
|
@ -141,10 +137,6 @@ AutomationLine::~AutomationLine ()
|
|||
delete *i;
|
||||
}
|
||||
control_points.clear ();
|
||||
|
||||
if (_our_time_converter) {
|
||||
delete _time_converter;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -302,13 +294,11 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
|
|||
y = min (1.0, y);
|
||||
y = _height - (y * _height);
|
||||
|
||||
double const x = trackview.editor().sample_to_pixel_unrounded (_time_converter->to((*cp.model())->when) - _offset);
|
||||
|
||||
trackview.editor().begin_reversible_command (_("automation event move"));
|
||||
trackview.editor().session()->add_command (
|
||||
new MementoCommand<AutomationList> (memento_command_binder(), &get_state(), 0));
|
||||
|
||||
cp.move_to (x, y, ControlPoint::Full);
|
||||
cp.move_to (cp.get_x(), y, ControlPoint::Full);
|
||||
|
||||
alist->freeze ();
|
||||
sync_model_with_view_point (cp);
|
||||
|
@ -787,7 +777,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
|||
|
||||
/* if xval has not changed, set it directly from the model to avoid rounding errors */
|
||||
|
||||
timepos_t model_x = alist->control_point_time (**(cp.model()));
|
||||
timepos_t model_x = (*cp.model())->when;
|
||||
|
||||
if (view_x != trackview.editor().time_to_pixel_unrounded (model_x.earlier (_offset))) {
|
||||
/* convert from view coordinates, via pixels->samples->timepos_t
|
||||
|
@ -800,7 +790,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
|||
|
||||
view_to_model_coord_y (view_y);
|
||||
|
||||
alist->modify (cp.model(), view_x, view_y);
|
||||
alist->modify (cp.model(), model_x, view_y);
|
||||
|
||||
/* convert back from model to view y for clamping position (for integer/boolean/etc) */
|
||||
model_to_view_coord_y (view_y);
|
||||
|
@ -898,20 +888,15 @@ AutomationLine::remove_point (ControlPoint& cp)
|
|||
* @param result Filled in with selectable things; in this case, ControlPoints.
|
||||
*/
|
||||
void
|
||||
AutomationLine::get_selectables (samplepos_t start, samplepos_t end, double botfrac, double topfrac, list<Selectable*>& results)
|
||||
AutomationLine::get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list<Selectable*>& results)
|
||||
{
|
||||
/* convert fractions to display coordinates with 0 at the top of the track */
|
||||
double const bot_track = (1 - topfrac) * trackview.current_height ();
|
||||
double const top_track = (1 - botfrac) * trackview.current_height ();
|
||||
|
||||
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
|
||||
double const model_when = (*(*i)->model())->when;
|
||||
|
||||
/* model_when is relative to the start of the source, so we just need to add on the origin_b here
|
||||
(as it is the session sample position of the start of the source)
|
||||
*/
|
||||
|
||||
samplepos_t const session_samples_when = _time_converter->to (model_when) + _time_converter->origin_b ();
|
||||
timepos_t const session_samples_when = timepos_t (session_sample_position ((*i)->model()));
|
||||
|
||||
if (session_samples_when >= start && session_samples_when <= end && (*i)->get_y() >= bot_track && (*i)->get_y() <= top_track) {
|
||||
results.push_back (*i);
|
||||
|
@ -994,20 +979,19 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
|
|||
|
||||
for (AutomationList::iterator ai = e.begin(); ai != e.end(); ++ai, ++pi) {
|
||||
|
||||
double tx = (*ai)->when;
|
||||
double ty = (*ai)->value;
|
||||
|
||||
/* convert from model coordinates to canonical view coordinates */
|
||||
|
||||
model_to_view_coord (tx, ty);
|
||||
timepos_t tx = model_to_view_coord (**ai, ty);
|
||||
|
||||
if (isnan_local (tx) || isnan_local (ty)) {
|
||||
if (isnan_local (ty)) {
|
||||
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
|
||||
_name) << endmsg;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tx >= max_samplepos || tx < 0 || tx >= _maximum_time) {
|
||||
if (tx >= timepos_t::max (tx.time_domain()) || tx.negative() || tx >= _maximum_time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1015,7 +999,7 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
|
|||
* zoom and scroll into account).
|
||||
*/
|
||||
|
||||
tx = trackview.editor().sample_to_pixel_unrounded (tx);
|
||||
double px = trackview.editor().time_to_pixel_unrounded (tx);
|
||||
|
||||
/* convert from canonical view height (0..1.0) to actual
|
||||
* height coordinates (using X11's top-left rooted system)
|
||||
|
@ -1023,7 +1007,7 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
|
|||
|
||||
ty = _height - (ty * _height);
|
||||
|
||||
add_visible_control_point (vp, pi, tx, ty, ai, np);
|
||||
add_visible_control_point (vp, pi, px, ty, ai, np);
|
||||
vp++;
|
||||
}
|
||||
|
||||
|
@ -1187,18 +1171,20 @@ AutomationLine::set_state (const XMLNode &node, int version)
|
|||
Temporal::timepos_t
|
||||
AutomationLine::view_to_model_coord (double x, double& y) const
|
||||
{
|
||||
assert (alist->time_style() != Temporal::BarTime);
|
||||
assert (alist->time_domain() != Temporal::BarTime);
|
||||
|
||||
view_to_model_coord_y (y);
|
||||
|
||||
Temporal::timepos_t w;
|
||||
|
||||
switch (alist->time_style()) {
|
||||
#warning NUTEMPO FIX ME ... this accepts view coordinate as double and things it can infer beats etc
|
||||
|
||||
switch (alist->time_domain()) {
|
||||
case Temporal::AudioTime:
|
||||
return timepos_t (samplepos_t (x));
|
||||
break;
|
||||
case Temporal::BeatTime:
|
||||
return timepos_t (Beats::from_double (x));
|
||||
return timepos_t (Temporal::Beats::from_double (x));
|
||||
break;
|
||||
default:
|
||||
/*NOTREACHED*/
|
||||
|
@ -1275,12 +1261,12 @@ AutomationLine::model_to_view_coord_y (double& y) const
|
|||
y = _desc.to_interface (y);
|
||||
}
|
||||
|
||||
double
|
||||
timepos_t
|
||||
AutomationLine::model_to_view_coord (Evoral::ControlEvent const & ev, double& y) const
|
||||
{
|
||||
Temporal::timepos_t w (ev.when());
|
||||
Temporal::timepos_t w (ev.when);
|
||||
model_to_view_coord_y (y);
|
||||
return (w).earlier (_offset).samples();
|
||||
return (w).earlier (_offset);
|
||||
}
|
||||
|
||||
/** Called when our list has announced that its interpolation style has changed */
|
||||
|
@ -1373,10 +1359,10 @@ AutomationLine::set_maximum_time (Temporal::timepos_t const & t)
|
|||
|
||||
|
||||
/** @return min and max x positions of points that are in the list, in session samples */
|
||||
pair<samplepos_t, samplepos_t>
|
||||
pair<timepos_t, timepos_t>
|
||||
AutomationLine::get_point_x_range () const
|
||||
{
|
||||
pair<samplepos_t, samplepos_t> r (max_samplepos, 0);
|
||||
pair<timepos_t, timepos_t> r (timepos_t::max (the_list()->time_domain()), timepos_t::zero (the_list()->time_domain()));
|
||||
|
||||
for (AutomationList::const_iterator i = the_list()->begin(); i != the_list()->end(); ++i) {
|
||||
r.first = min (r.first, session_position (i));
|
||||
|
@ -1389,17 +1375,17 @@ AutomationLine::get_point_x_range () const
|
|||
samplepos_t
|
||||
AutomationLine::session_sample_position (AutomationList::const_iterator p) const
|
||||
{
|
||||
return alist->control_point_time (ev).sample() + _offset.samples() + _distance_measure.origin().samples();
|
||||
return (*p)->when.samples() + _offset.samples() + _distance_measure.origin().samples();
|
||||
}
|
||||
|
||||
timepos_t
|
||||
AutomationLine::session_position (AutomationList::const_iterator p) const
|
||||
{
|
||||
return alist->control_point_time (ev) + _offset + _distance_measure.origin();
|
||||
return (*p)->when + _offset + _distance_measure.origin();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationLine::set_offset (samplepos_t off)
|
||||
AutomationLine::set_offset (timecnt_t const & off)
|
||||
{
|
||||
if (_offset == off) {
|
||||
return;
|
||||
|
|
|
@ -71,7 +71,8 @@ public:
|
|||
TimeAxisView& tv,
|
||||
ArdourCanvas::Item& parent,
|
||||
boost::shared_ptr<ARDOUR::AutomationList> al,
|
||||
const ARDOUR::ParameterDescriptor& desc);
|
||||
const ARDOUR::ParameterDescriptor& desc,
|
||||
Temporal::DistanceMeasure const &);
|
||||
|
||||
virtual ~AutomationLine ();
|
||||
|
||||
|
@ -125,7 +126,7 @@ public:
|
|||
std::string fraction_to_string (double) const;
|
||||
std::string delta_to_string (double) const;
|
||||
double string_to_fraction (std::string const &) const;
|
||||
Temporal::timepos_t view_to_model_coord (double& x, double& y) const;
|
||||
Temporal::timepos_t view_to_model_coord (double x, double& y) const;
|
||||
void view_to_model_coord_y (double &) const;
|
||||
Temporal::timepos_t model_to_view_coord (Evoral::ControlEvent const &, double& y) const;
|
||||
void model_to_view_coord_y (double &) const;
|
||||
|
@ -150,7 +151,7 @@ public:
|
|||
|
||||
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
||||
|
||||
std::pair<ARDOUR::samplepos_t, ARDOUR::samplepos_t> get_point_x_range () const;
|
||||
std::pair<Temporal::timepos_t, Temporal::timepos_t> get_point_x_range () const;
|
||||
|
||||
void set_maximum_time (Temporal::timepos_t const &);
|
||||
Temporal::timepos_t maximum_time () const {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
n/*
|
||||
* Copyright (C) 2007-2015 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2008-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
|
||||
|
@ -208,8 +208,7 @@ AutomationRegionView::add_automation_event (GdkEvent *, timepos_t const & w, dou
|
|||
|
||||
XMLNode& before = _line->the_list()->get_state();
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (_line->the_list()->editor_add (when_d, y, with_guard_points)) {
|
||||
n if (_line->the_list()->editor_add (when, y, with_guard_points)) {
|
||||
|
||||
if (ac->automation_state () == ARDOUR::Off) {
|
||||
ac->set_automation_state (ARDOUR::Play);
|
||||
|
@ -218,9 +217,6 @@ AutomationRegionView::add_automation_event (GdkEvent *, timepos_t const & w, dou
|
|||
RouteTimeAxisView::signal_ctrl_touched (false);
|
||||
}
|
||||
|
||||
=======
|
||||
if (_line->the_list()->editor_add (when, y, with_guard_points)) {
|
||||
>>>>>>> intermediate, unfinished snapshot of ongoing timeline types work on GTK GUI
|
||||
view->editor().begin_reversible_command (_("add automation event"));
|
||||
|
||||
XMLNode& after = _line->the_list()->get_state();
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "pbd/unwind.h"
|
||||
|
||||
#include "ardour/automation_control.h"
|
||||
#include "ardour/beats_samples_converter.h"
|
||||
#include "ardour/automation_list.h"
|
||||
#include "ardour/event_type_map.h"
|
||||
#include "ardour/parameter_types.h"
|
||||
#include "ardour/profile.h"
|
||||
|
@ -299,13 +299,15 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
|||
|
||||
assert (_control);
|
||||
|
||||
#warning NUTEMPO new tempo map API required
|
||||
#if 0
|
||||
boost::shared_ptr<AutomationLine> line (
|
||||
new AutomationLine (
|
||||
ARDOUR::EventTypeMap::instance().to_symbol(_parameter),
|
||||
*this,
|
||||
*_canvas_display,
|
||||
_control->alist(),
|
||||
_control->desc()
|
||||
_control->desc(),
|
||||
Temporal::DistanceMeasure (_session->tempo_map(), timepos_t()) /* default distance measure, origin at absolute zero */
|
||||
)
|
||||
);
|
||||
|
@ -314,6 +316,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
|||
line->set_fill (true);
|
||||
line->queue_reset ();
|
||||
add_line (line);
|
||||
#endif 0
|
||||
}
|
||||
|
||||
/* make sure labels etc. are correct */
|
||||
|
@ -768,14 +771,14 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, samplepos_t sampl
|
|||
return;
|
||||
}
|
||||
|
||||
MusicSample when (sample, 0);
|
||||
timepos_t when (sample);
|
||||
_editor.snap_to_with_modifier (when, event);
|
||||
|
||||
if (UIConfiguration::instance().get_new_automation_points_on_lane()) {
|
||||
if (_control->list()->size () == 0) {
|
||||
y = _control->get_value ();
|
||||
} else {
|
||||
y = _control->list()->eval (when.sample);
|
||||
y = _control->list()->eval (when);
|
||||
}
|
||||
} else {
|
||||
double x = 0;
|
||||
|
@ -789,7 +792,7 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, samplepos_t sampl
|
|||
XMLNode& before = list->get_state();
|
||||
std::list<Selectable*> results;
|
||||
|
||||
if (list->editor_add (when.sample, y, with_guard_points)) {
|
||||
if (list->editor_add (when, y, with_guard_points)) {
|
||||
|
||||
if (_control->automation_state () == ARDOUR::Off) {
|
||||
_control->set_automation_state (ARDOUR::Play);
|
||||
|
@ -802,7 +805,7 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, samplepos_t sampl
|
|||
_editor.begin_reversible_command (_("add automation event"));
|
||||
_session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
|
||||
|
||||
_line->get_selectables (when.sample, when.sample, 0.0, 1.0, results);
|
||||
_line->get_selectables (when, when, 0.0, 1.0, results);
|
||||
_editor.get_selection ().set (results);
|
||||
|
||||
_editor.commit_reversible_command ();
|
||||
|
@ -811,7 +814,7 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, samplepos_t sampl
|
|||
}
|
||||
|
||||
bool
|
||||
AutomationTimeAxisView::paste (samplepos_t pos, const Selection& selection, PasteContext& ctx, const int32_t divisions)
|
||||
AutomationTimeAxisView::paste (timepos_t const & pos, const Selection& selection, PasteContext& ctx)
|
||||
{
|
||||
if (_line) {
|
||||
return paste_one (pos, ctx.count, ctx.times, selection, ctx.counts, ctx.greedy);
|
||||
|
@ -832,7 +835,7 @@ AutomationTimeAxisView::paste (samplepos_t pos, const Selection& selection, Past
|
|||
}
|
||||
|
||||
bool
|
||||
AutomationTimeAxisView::paste_one (samplepos_t pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts, bool greedy)
|
||||
AutomationTimeAxisView::paste_one (timepos_t const & pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts, bool greedy)
|
||||
{
|
||||
boost::shared_ptr<AutomationList> alist(_line->the_list());
|
||||
|
||||
|
@ -858,33 +861,29 @@ AutomationTimeAxisView::paste_one (samplepos_t pos, unsigned paste_count, float
|
|||
Temporal::timecnt_t len = (*p)->length();
|
||||
Temporal::timepos_t tpos (pos);
|
||||
|
||||
assert (line()->the_list()->time_style() != Temporal::BarTime);
|
||||
|
||||
switch (line()->the_list()->time_style()) {
|
||||
switch (line()->the_list()->time_domain()) {
|
||||
case Temporal::BeatTime:
|
||||
tpos += _editor.get_paste_offset (pos, paste_count > 0 ? 1 : 0, len);
|
||||
break;
|
||||
case Temporal::AudioTime:
|
||||
tpos += _editor.get_paste_offset (pos, paste_count, len);
|
||||
break;
|
||||
case Temporal::BarTime:
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* convert position to model's unit and position */
|
||||
Temporal::DistanceMeasure const & dm (_line->distance_measure());
|
||||
Temporal::timepos_t model_pos = dm (_line->distance_measure().origin().distance (tpos), line()->the_list()->time_style());
|
||||
Temporal::timepos_t model_pos = dm (_line->distance_measure().origin().distance (tpos), line()->the_list()->time_domain());
|
||||
|
||||
XMLNode &before = alist->get_state();
|
||||
alist->paste (**p, model_pos, _session->tempo_map());
|
||||
#warning NUTEMPO FIX THIS ... WHY DOES the paste call get a type error from the compiler
|
||||
//alist->paste (**p, model_pos, _session->tempo_map());
|
||||
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AutomationTimeAxisView::get_selectables (samplepos_t start, samplepos_t end, double top, double bot, list<Selectable*>& results, bool /*within*/)
|
||||
AutomationTimeAxisView::get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list<Selectable*>& results, bool /*within*/)
|
||||
{
|
||||
if (!_line && !_view) {
|
||||
return;
|
||||
|
@ -1148,9 +1147,9 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
|||
XMLNode &before = alist->get_state();
|
||||
|
||||
/* convert time selection to automation list model coordinates */
|
||||
const Evoral::TimeConverter<double, ARDOUR::samplepos_t>& tc = line.time_converter ();
|
||||
double const start = tc.from (selection.time.front().start - tc.origin_b ());
|
||||
double const end = tc.from (selection.time.front().end - tc.origin_b ());
|
||||
/* convert time selection to automation list model coordinates */
|
||||
timepos_t start = selection.time.front().start().earlier (line.distance_measure().origin());
|
||||
timepos_t end = selection.time.front().end().earlier (line.distance_measure().origin());
|
||||
|
||||
switch (op) {
|
||||
case Delete:
|
||||
|
@ -1181,9 +1180,9 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
|||
|
||||
if (what_we_got) {
|
||||
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
|
||||
double when = (*x)->when;
|
||||
timepos_t when = (*x)->when;
|
||||
double val = (*x)->value;
|
||||
line.model_to_view_coord (when, val);
|
||||
line.model_to_view_coord (**x, val);
|
||||
(*x)->when = when;
|
||||
(*x)->value = val;
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ protected:
|
|||
void build_display_menu ();
|
||||
|
||||
void cut_copy_clear_one (AutomationLine&, Selection&, Editing::CutCopyOp);
|
||||
bool paste_one (ARDOUR::samplepos_t, unsigned, float times, const Selection&, ItemCounts& counts, bool greedy=false);
|
||||
bool paste_one (Temporal::timepos_t const &, unsigned, float times, const Selection&, ItemCounts& counts, bool greedy=false);
|
||||
void route_going_away ();
|
||||
|
||||
void set_automation_state (ARDOUR::AutoState);
|
||||
|
|
|
@ -36,7 +36,7 @@ curvetest (string filename)
|
|||
stringstream line;
|
||||
//Evoral::Parameter param(GainAutomation, -1.0, +1.0, 0.0);
|
||||
Evoral::Parameter param(GainAutomation);
|
||||
AutomationList al (param);
|
||||
AutomationList al (param, Temporal::AudioTime);
|
||||
double minx = DBL_MAX;
|
||||
double maxx = DBL_MIN;
|
||||
|
||||
|
@ -58,13 +58,13 @@ curvetest (string filename)
|
|||
maxx = x;
|
||||
}
|
||||
|
||||
al.add (x, y);
|
||||
al.add (Temporal::timepos_t (x), y);
|
||||
}
|
||||
|
||||
|
||||
float foo[1024];
|
||||
|
||||
al.curve().get_vector (minx, maxx, foo, 1024);
|
||||
al.curve().get_vector (timepos_t (minx), timepos_t (maxx), foo, 1024);
|
||||
|
||||
for (int i = 0; i < 1024; ++i) {
|
||||
cout << minx + (((double) i / 1024.0) * (maxx - minx)) << ' ' << foo[i] << endl;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Temporal;
|
||||
using namespace Gtk;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
|
@ -95,8 +96,11 @@ EditNoteDialog::EditNoteDialog (MidiRegionView* rv, set<NoteBase*> n)
|
|||
|
||||
_time_clock.set_session (_region_view->get_time_axis_view().session ());
|
||||
_time_clock.set_mode (AudioClock::BBT);
|
||||
_time_clock.set (_region_view->source_relative_time_converter().to
|
||||
((*_events.begin())->note()->time()) + (_region_view->region()->position() - _region_view->region()->start()), true);
|
||||
|
||||
timecnt_t dur = _region_view->source_relative_distance (timecnt_t ((*_events.begin())->note()->time(), timepos_t()), BeatTime);
|
||||
timepos_t pos = _region_view->region()->source_position() + dur;
|
||||
|
||||
_time_clock.set (pos, true);
|
||||
|
||||
l = manage (left_aligned_label (_("Length")));
|
||||
table->attach (*l, 0, 1, r, r + 1);
|
||||
|
@ -106,10 +110,15 @@ EditNoteDialog::EditNoteDialog (MidiRegionView* rv, set<NoteBase*> n)
|
|||
|
||||
_length_clock.set_session (_region_view->get_time_axis_view().session ());
|
||||
_length_clock.set_mode (AudioClock::BBT);
|
||||
_length_clock.set (
|
||||
_region_view->region_relative_time_converter().to ((*_events.begin())->note()->end_time ()) + _region_view->region()->position(),
|
||||
true,
|
||||
_region_view->region_relative_time_converter().to ((*_events.begin())->note()->time ()) + _region_view->region()->position());
|
||||
|
||||
dur = _region_view->region_relative_distance (timecnt_t ((*_events.begin())->note()->end_time (), timepos_t()), BarTime);
|
||||
pos = _region_view->region()->nt_position() + dur;
|
||||
timecnt_t offset;
|
||||
dur = _region_view->region_relative_distance (timecnt_t ((*_events.begin())->note()->time (), timepos_t()), BarTime);
|
||||
offset = timecnt_t (_region_view->region()->nt_position(), timepos_t()) + dur;
|
||||
|
||||
_length_clock.set_is_duration (true, pos);
|
||||
_length_clock.set_duration (offset, true);
|
||||
|
||||
/* Set up `set all notes...' buttons' sensitivity */
|
||||
|
||||
|
@ -199,27 +208,41 @@ EditNoteDialog::done (int r)
|
|||
}
|
||||
}
|
||||
|
||||
samplecnt_t const region_samples = _time_clock.current_time() - (_region_view->region()->position() - _region_view->region()->start());
|
||||
Temporal::Beats const t = _region_view->source_relative_time_converter().from (region_samples);
|
||||
timepos_t source_start = _region_view->region()->nt_position().earlier (_region_view->region()->nt_start());
|
||||
|
||||
/* convert current clock time into an offset from the start of the source */
|
||||
|
||||
timepos_t time_clock_source_relative = _time_clock.current_time().earlier (source_start);
|
||||
|
||||
/* convert that into a position in Beats - this will be the new note time (as an offset inside the source) */
|
||||
|
||||
Beats const new_note_time_source_relative_beats = time_clock_source_relative.beats ();
|
||||
|
||||
if (!_time_all.get_sensitive() || _time_all.get_active ()) {
|
||||
for (set<NoteBase*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
if (t != (*i)->note()->time()) {
|
||||
_region_view->change_note_time (*i, t);
|
||||
if (new_note_time_source_relative_beats != (*i)->note()->time()) {
|
||||
_region_view->change_note_time (*i, new_note_time_source_relative_beats);
|
||||
had_change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_length_all.get_sensitive() || _length_all.get_active ()) {
|
||||
|
||||
|
||||
/* get current note duration, interpreted as beats at the time indicated by the _time_clock (the new note position) */
|
||||
Beats const duration = _length_clock.current_duration (_time_clock.current_time()).beats ();
|
||||
|
||||
/* compute end of note */
|
||||
Beats const new_note_end_source_relative_beats = new_note_time_source_relative_beats + duration;
|
||||
|
||||
for (set<NoteBase*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
samplepos_t const note_end_sample = region_samples + _length_clock.current_duration (_time_clock.current_time());
|
||||
Temporal::Beats const d = _region_view->source_relative_time_converter().from (note_end_sample) - (*i)->note()->time();
|
||||
if (d != (*i)->note()->length()) {
|
||||
_region_view->change_note_length (*i, d);
|
||||
Beats const new_note_length_beats = new_note_end_source_relative_beats - (*i)->note()->time();
|
||||
if (new_note_length_beats != (*i)->note()->length()) {
|
||||
_region_view->change_note_length (*i, new_note_length_beats);
|
||||
had_change = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!had_change) {
|
||||
|
|
|
@ -6383,3 +6383,27 @@ Editor::use_own_window (bool and_fill_it)
|
|||
|
||||
return win;
|
||||
}
|
||||
|
||||
double
|
||||
Editor::time_to_pixel (timepos_t const & pos) const
|
||||
{
|
||||
return sample_to_pixel (pos.samples());
|
||||
}
|
||||
|
||||
double
|
||||
Editor::time_to_pixel_unrounded (timepos_t const & pos) const
|
||||
{
|
||||
return sample_to_pixel_unrounded (pos.samples());
|
||||
}
|
||||
|
||||
double
|
||||
Editor::duration_to_pixels (timecnt_t const & dur) const
|
||||
{
|
||||
return sample_to_pixel (dur.samples());
|
||||
}
|
||||
|
||||
double
|
||||
Editor::duration_to_pixels_unrounded (timecnt_t const & dur) const
|
||||
{
|
||||
return sample_to_pixel_unrounded (dur.samples());
|
||||
}
|
||||
|
|
|
@ -262,6 +262,12 @@ public:
|
|||
return sample / (double) samples_per_pixel;
|
||||
}
|
||||
|
||||
double time_to_pixel (Temporal::timepos_t const & pos) const;
|
||||
double time_to_pixel_unrounded (Temporal::timepos_t const & pos) const;
|
||||
|
||||
double duration_to_pixels (Temporal::timecnt_t const & pos) const;
|
||||
double duration_to_pixels_unrounded (Temporal::timecnt_t const & pos) const;
|
||||
|
||||
/* selection */
|
||||
|
||||
Selection& get_selection() const { return *selection; }
|
||||
|
@ -569,7 +575,7 @@ public:
|
|||
void metric_get_minsec (std::vector<ArdourCanvas::Ruler::Mark>&, gdouble, gdouble, gint);
|
||||
|
||||
/* editing operations that need to be public */
|
||||
void mouse_add_new_marker (Temporal::timepos_t const & where, bool is_cd=false);
|
||||
void mouse_add_new_marker (Temporal::timepos_t where, bool is_cd=false);
|
||||
void split_regions_at (Temporal::timepos_t const & , RegionSelection&);
|
||||
void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false);
|
||||
RegionSelection get_regions_from_selection_and_mouse (Temporal::timepos_t const &);
|
||||
|
@ -578,8 +584,8 @@ public:
|
|||
|
||||
void mouse_brush_insert_region (RegionView*, samplepos_t pos);
|
||||
|
||||
void mouse_add_new_tempo_event (samplepos_t where);
|
||||
void mouse_add_new_meter_event (samplepos_t where);
|
||||
void mouse_add_new_tempo_event (Temporal::timepos_t where);
|
||||
void mouse_add_new_meter_event (Temporal::timepos_t where);
|
||||
void edit_tempo_section (ARDOUR::TempoSection*);
|
||||
void edit_meter_section (ARDOUR::MeterSection*);
|
||||
|
||||
|
@ -755,9 +761,9 @@ private:
|
|||
|
||||
void hide_marker (ArdourCanvas::Item*, GdkEvent*);
|
||||
void clear_marker_display ();
|
||||
void mouse_add_new_range (samplepos_t);
|
||||
void mouse_add_new_loop (samplepos_t);
|
||||
void mouse_add_new_punch (samplepos_t);
|
||||
void mouse_add_new_range (Temporal::timepos_t);
|
||||
void mouse_add_new_loop (Temporal::timepos_t);
|
||||
void mouse_add_new_punch (Temporal::timepos_t);
|
||||
bool choose_new_marker_name(std::string &name, bool is_range=false);
|
||||
void update_cd_marker_display ();
|
||||
void ensure_cd_marker_updated (LocationMarkers* lam, ARDOUR::Location* location);
|
||||
|
@ -945,7 +951,7 @@ private:
|
|||
void compute_fixed_ruler_scale (); //calculates the RulerScale of the fixed rulers
|
||||
void update_fixed_rulers ();
|
||||
void update_tempo_based_rulers ();
|
||||
void popup_ruler_menu (samplepos_t where = 0, ItemType type = RegionItem);
|
||||
void popup_ruler_menu (Temporal::timepos_t const & where = Temporal::timepos_t (), ItemType type = RegionItem);
|
||||
void update_ruler_visibility ();
|
||||
void toggle_ruler_visibility ();
|
||||
void ruler_toggled (int);
|
||||
|
|
|
@ -668,7 +668,7 @@ Editor::LocationMarkers::setup_lines ()
|
|||
}
|
||||
|
||||
void
|
||||
Editor::mouse_add_new_marker (timepos_t const & where, bool is_cd)
|
||||
Editor::mouse_add_new_marker (timepos_t where, bool is_cd)
|
||||
{
|
||||
string markername;
|
||||
int flags = (is_cd ? Location::IsCDMarker|Location::IsMark : Location::IsMark);
|
||||
|
@ -700,7 +700,7 @@ Editor::mouse_add_new_marker (timepos_t const & where, bool is_cd)
|
|||
}
|
||||
|
||||
void
|
||||
Editor::mouse_add_new_loop (samplepos_t where)
|
||||
Editor::mouse_add_new_loop (timepos_t where)
|
||||
{
|
||||
if (!_session) {
|
||||
return;
|
||||
|
@ -710,13 +710,13 @@ Editor::mouse_add_new_loop (samplepos_t where)
|
|||
it's reasonably easy to manipulate after creation.
|
||||
*/
|
||||
|
||||
samplepos_t const end = where + current_page_samples() / 8;
|
||||
timepos_t const end = where + timecnt_t (current_page_samples() / 8);
|
||||
|
||||
set_loop_range (timepos_t (where), timepos_t (end), _("set loop range"));
|
||||
set_loop_range (where, timepos_t (end), _("set loop range"));
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mouse_add_new_punch (samplepos_t where)
|
||||
Editor::mouse_add_new_punch (timepos_t where)
|
||||
{
|
||||
if (!_session) {
|
||||
return;
|
||||
|
@ -726,13 +726,13 @@ Editor::mouse_add_new_punch (samplepos_t where)
|
|||
it's reasonably easy to manipulate after creation.
|
||||
*/
|
||||
|
||||
samplepos_t const end = where + current_page_samples() / 8;
|
||||
timepos_t const end = where + timecnt_t (current_page_samples() / 8);
|
||||
|
||||
set_punch_range (timepos_t (where), timepos_t (end), _("set punch range"));
|
||||
set_punch_range (where, end, _("set punch range"));
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mouse_add_new_range (samplepos_t where)
|
||||
Editor::mouse_add_new_range (timepos_t where)
|
||||
{
|
||||
if (!_session) {
|
||||
return;
|
||||
|
@ -742,7 +742,7 @@ Editor::mouse_add_new_range (samplepos_t where)
|
|||
it's reasonably easy to manipulate after creation.
|
||||
*/
|
||||
|
||||
samplepos_t const end = where + current_page_samples() / 8;
|
||||
timepos_t const end = where + timecnt_t (current_page_samples() / 8);
|
||||
|
||||
string name;
|
||||
_session->locations()->next_available_name (name, _("range"));
|
||||
|
|
|
@ -1626,7 +1626,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
case SamplesRulerItem:
|
||||
case MinsecRulerItem:
|
||||
case BBTRulerItem:
|
||||
popup_ruler_menu (where.sample, item_type);
|
||||
popup_ruler_menu (timepos_t (where), item_type);
|
||||
break;
|
||||
|
||||
case MarkerItem:
|
||||
|
|
|
@ -1805,7 +1805,7 @@ EditorRoutes::solo_changed_so_update_mute ()
|
|||
void
|
||||
EditorRoutes::show_tracks_with_regions_at_playhead ()
|
||||
{
|
||||
boost::shared_ptr<RouteList> const r = _session->get_routes_with_regions_at (_session->transport_sample ());
|
||||
boost::shared_ptr<RouteList> const r = _session->get_routes_with_regions_at (timepos_t (_session->transport_sample ()));
|
||||
|
||||
set<TimeAxisView*> show;
|
||||
for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
|
||||
|
|
|
@ -201,7 +201,7 @@ Editor::ruler_label_button_release (GdkEventButton* ev)
|
|||
}
|
||||
|
||||
void
|
||||
Editor::popup_ruler_menu (samplepos_t where, ItemType t)
|
||||
Editor::popup_ruler_menu (timepos_t const & where, ItemType t)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
|
|
|
@ -402,15 +402,18 @@ Editor::maybe_draw_grid_lines ()
|
|||
}
|
||||
|
||||
void
|
||||
Editor::mouse_add_new_tempo_event (samplepos_t sample)
|
||||
Editor::mouse_add_new_tempo_event (timepos_t pos)
|
||||
{
|
||||
if (_session == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#warning NUTEMPO requires new tempo map API
|
||||
#if 0
|
||||
TempoMap& map(_session->tempo_map());
|
||||
|
||||
begin_reversible_command (_("add tempo mark"));
|
||||
|
||||
const double pulse = map.exact_qn_at_sample (sample, get_grid_music_divisions (0)) / 4.0;
|
||||
|
||||
if (pulse > 0.0) {
|
||||
|
@ -422,20 +425,21 @@ Editor::mouse_add_new_tempo_event (samplepos_t sample)
|
|||
_session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
#endif
|
||||
//map.dump (cerr);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mouse_add_new_meter_event (samplepos_t sample)
|
||||
Editor::mouse_add_new_meter_event (timepos_t pos)
|
||||
{
|
||||
if (_session == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#warning NUTEMPO requires new tempo map API
|
||||
#if 0
|
||||
TempoMap& map(_session->tempo_map());
|
||||
MeterDialog meter_dialog (map, sample, _("add"));
|
||||
MeterDialog meter_dialog (map, pos, _("add"));
|
||||
|
||||
switch (meter_dialog.run ()) {
|
||||
case RESPONSE_ACCEPT:
|
||||
|
@ -454,6 +458,7 @@ Editor::mouse_add_new_meter_event (samplepos_t sample)
|
|||
|
||||
const double al_sample = map.sample_at_bbt (requested);
|
||||
begin_reversible_command (_("add meter mark"));
|
||||
|
||||
XMLNode &before = map.get_state();
|
||||
|
||||
if (meter_dialog.get_lock_style() == MusicTime) {
|
||||
|
@ -464,7 +469,7 @@ Editor::mouse_add_new_meter_event (samplepos_t sample)
|
|||
|
||||
_session->add_command(new MementoCommand<TempoMap>(map, &before, &map.get_state()));
|
||||
commit_reversible_command ();
|
||||
|
||||
#endif
|
||||
//map.dump (cerr);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ Editor::time_stretch (RegionSelection& regions, float fraction)
|
|||
stretch.run (*i);
|
||||
|
||||
playlist->replace_region (regions.front()->region(), stretch.results[0],
|
||||
regions.front()->region()->position());
|
||||
regions.front()->region()->nt_position());
|
||||
midi_playlists_affected.insert (playlist);
|
||||
}
|
||||
|
||||
|
@ -168,9 +168,9 @@ Editor::time_fx (RegionList& regions, float val, bool pitching)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const samplecnt_t oldlen = (samplecnt_t) (regions.front()->length());
|
||||
const samplecnt_t newlen = (samplecnt_t) (regions.front()->length() * val);
|
||||
const samplecnt_t pos = regions.front()->position ();
|
||||
const timecnt_t oldlen = regions.front()->nt_length();
|
||||
const timecnt_t newlen = regions.front()->nt_length() * val;
|
||||
const timecnt_t pos = regions.front()->nt_position ();
|
||||
|
||||
current_timefx = new TimeFXDialog (*this, pitching, oldlen, newlen, pos);
|
||||
current_timefx->regions = regions;
|
||||
|
|
|
@ -584,7 +584,7 @@ ExportRegionDialog::init_gui ()
|
|||
void
|
||||
ExportRegionDialog::init_components ()
|
||||
{
|
||||
string loc_id = profile_manager->set_single_range (region.position(), region.position() + region.length(), region.name());
|
||||
string loc_id = profile_manager->set_single_range (region.nt_position(), region.nt_position() + region.nt_length(), region.name());
|
||||
|
||||
preset_selector.reset (new ExportPresetSelector ());
|
||||
timespan_selector.reset (new ExportTimespanSelectorSingle (_session, profile_manager, loc_id));
|
||||
|
|
|
@ -731,7 +731,7 @@ ExportVideoDialog::launch_export ()
|
|||
end += av_offset;
|
||||
}
|
||||
else if (insnd_combo.get_active_row_number() == 2) {
|
||||
start = ARDOUR_UI::instance()->video_timeline->quantify_samples_to_apv(export_range.start());
|
||||
start = ARDOUR_UI::instance()->video_timeline->quantify_samples_to_apv(export_range.start_sample());
|
||||
end = ARDOUR_UI::instance()->video_timeline->quantify_samples_to_apv(export_range.end_sample());
|
||||
}
|
||||
if (end <= 0) {
|
||||
|
@ -954,7 +954,7 @@ ExportVideoDialog::encode_pass (int pass)
|
|||
duration_s = (double)duration_f / (double)_session->nominal_sample_rate();
|
||||
} else if (insnd_combo.get_active_row_number() == 2) {
|
||||
/* selected range */
|
||||
duration_s = export_range.length() / (double)_session->nominal_sample_rate();
|
||||
duration_s = export_range.length_samples() / (double)_session->nominal_sample_rate();
|
||||
} else {
|
||||
/* video start to end */
|
||||
samplecnt_t duration_f = ARDOUR_UI::instance()->video_timeline->get_duration();
|
||||
|
@ -975,7 +975,7 @@ ExportVideoDialog::encode_pass (int pass)
|
|||
start = _session->current_start_sample();
|
||||
snend = _session->current_end_sample();
|
||||
} else {
|
||||
start = export_range.start();
|
||||
start = export_range.start_sample();
|
||||
snend = export_range.end_sample();
|
||||
}
|
||||
|
||||
|
|
|
@ -110,9 +110,6 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
|
|||
: RegionView (parent, tv, r, spu, basic_color)
|
||||
, _current_range_min(0)
|
||||
, _current_range_max(0)
|
||||
, _region_relative_time_converter(r->session().tempo_map(), Temporal::Beats::from_double (r->position()))
|
||||
, _source_relative_time_converter(r->session().tempo_map(), Temporal::Beats::from_double (r->position() - r->start()))
|
||||
, _region_relative_time_converter_double(r->session().tempo_map(), Temporal::Beats::from_double (r->position()))
|
||||
, _active_notes(0)
|
||||
, _note_group (new ArdourCanvas::Container (group))
|
||||
, _note_diff_command (0)
|
||||
|
@ -155,9 +152,6 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
|
|||
: RegionView (parent, tv, r, spu, basic_color, recording, visibility)
|
||||
, _current_range_min(0)
|
||||
, _current_range_max(0)
|
||||
, _region_relative_time_converter(r->session().tempo_map(), r->position())
|
||||
, _source_relative_time_converter(r->session().tempo_map(), r->position() - r->start())
|
||||
, _region_relative_time_converter_double(r->session().tempo_map(), r->position())
|
||||
, _active_notes(0)
|
||||
, _note_group (new ArdourCanvas::Container (group))
|
||||
, _note_diff_command (0)
|
||||
|
@ -209,9 +203,6 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
|
|||
, RegionView (other)
|
||||
, _current_range_min(0)
|
||||
, _current_range_max(0)
|
||||
, _region_relative_time_converter(other.region_relative_time_converter())
|
||||
, _source_relative_time_converter(other.source_relative_time_converter())
|
||||
, _region_relative_time_converter_double(other.region_relative_time_converter_double())
|
||||
, _active_notes(0)
|
||||
, _note_group (new ArdourCanvas::Container (get_canvas_group()))
|
||||
, _note_diff_command (0)
|
||||
|
@ -238,9 +229,6 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
|
|||
: RegionView (other, boost::shared_ptr<Region> (region))
|
||||
, _current_range_min(0)
|
||||
, _current_range_max(0)
|
||||
, _region_relative_time_converter(other.region_relative_time_converter())
|
||||
, _source_relative_time_converter(other.source_relative_time_converter())
|
||||
, _region_relative_time_converter_double(other.region_relative_time_converter_double())
|
||||
, _active_notes(0)
|
||||
, _note_group (new ArdourCanvas::Container (get_canvas_group()))
|
||||
, _note_diff_command (0)
|
||||
|
@ -863,8 +851,7 @@ MidiRegionView::create_note_at (samplepos_t t, double y, Temporal::Beats length,
|
|||
}
|
||||
|
||||
// Start of note in samples relative to region start
|
||||
const int32_t divisions = trackview.editor().get_grid_music_divisions (state);
|
||||
Temporal::Beats beat_time = snap_sample_to_grid_underneath (t, divisions, shift_snap);
|
||||
Temporal::Beats beat_time = snap_sample_to_grid_underneath (t, shift_snap);
|
||||
|
||||
const double note = view->y_to_note(y);
|
||||
const uint8_t chan = mtv->get_channel_for_add();
|
||||
|
@ -1261,12 +1248,12 @@ MidiRegionView::display_patch_changes_on_channel (uint8_t channel, bool active_c
|
|||
|
||||
if ((p = find_canvas_patch_change (*i)) != 0) {
|
||||
|
||||
const samplecnt_t region_samples = source_beats_to_region_samples ((*i)->time());
|
||||
const timepos_t region_time = _region->source_beats_to_region_time ((*i)->time());
|
||||
|
||||
if (region_samples < 0 || region_samples >= _region->length()) {
|
||||
if (region_time < timepos_t() || region_time >= _region->nt_length()) {
|
||||
p->hide();
|
||||
} else {
|
||||
const double x = trackview.editor().sample_to_pixel (region_samples);
|
||||
const double x = trackview.editor().time_to_pixel (region_time);
|
||||
p->canvas_item()->set_position (ArdourCanvas::Duple (x, 1.0));
|
||||
p->update_name ();
|
||||
|
||||
|
@ -1318,7 +1305,7 @@ MidiRegionView::display_sysexes()
|
|||
|
||||
for (MidiModel::SysExes::const_iterator i = _model->sysexes().begin(); i != _model->sysexes().end(); ++i) {
|
||||
MidiModel::SysExPtr sysex_ptr = *i;
|
||||
Temporal::Beats time = sysex_ptr->time();
|
||||
timepos_t time = timepos_t (sysex_ptr->time());
|
||||
|
||||
if ((*i)->is_spp() || (*i)->is_mtc_quarter() || (*i)->is_mtc_full()) {
|
||||
if (!display_periodic_messages) {
|
||||
|
@ -1336,7 +1323,7 @@ MidiRegionView::display_sysexes()
|
|||
}
|
||||
string text = str.str();
|
||||
|
||||
const double x = trackview.editor().sample_to_pixel(source_beats_to_region_samples(time));
|
||||
const double x = trackview.editor().time_to_pixel (_region->source_beats_to_region_time (time.beats()));
|
||||
|
||||
double height = midi_stream_view()->contents_height();
|
||||
|
||||
|
@ -1354,7 +1341,7 @@ MidiRegionView::display_sysexes()
|
|||
}
|
||||
|
||||
// Show unless message is beyond the region bounds
|
||||
if (time - mregion->start_beats() >= mregion->length_beats() || time < mregion->start_beats()) {
|
||||
if (_region->source_relative_position (time) >= _region->nt_length() || time < _region->nt_start()) {
|
||||
sysex->hide();
|
||||
} else {
|
||||
sysex->show();
|
||||
|
@ -1389,15 +1376,12 @@ MidiRegionView::region_resized (const PropertyChange& what_changed)
|
|||
RegionView::region_resized(what_changed); // calls RegionView::set_duration()
|
||||
|
||||
if (what_changed.contains (ARDOUR::Properties::position)) {
|
||||
_region_relative_time_converter.set_origin_b(_region->position());
|
||||
_region_relative_time_converter_double.set_origin_b(_region->position());
|
||||
/* reset_width dependent_items() redisplays model */
|
||||
|
||||
}
|
||||
|
||||
if (what_changed.contains (ARDOUR::Properties::start) ||
|
||||
what_changed.contains (ARDOUR::Properties::position)) {
|
||||
_source_relative_time_converter.set_origin_b (_region->position() - _region->start());
|
||||
}
|
||||
/* catch end and start trim so we can update the view*/
|
||||
if (!what_changed.contains (ARDOUR::Properties::start) &&
|
||||
|
@ -1481,7 +1465,7 @@ MidiRegionView::apply_note_range (uint8_t min, uint8_t max, bool force)
|
|||
GhostRegion*
|
||||
MidiRegionView::add_ghost (TimeAxisView& tv)
|
||||
{
|
||||
double unit_position = _region->position () / samples_per_pixel;
|
||||
double unit_position = trackview.editor().time_to_pixel (_region->nt_position ());
|
||||
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(&tv);
|
||||
MidiGhostRegion* ghost;
|
||||
|
||||
|
@ -1496,7 +1480,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
|
|||
|
||||
ghost->set_colors ();
|
||||
ghost->set_height ();
|
||||
ghost->set_duration (_region->length() / samples_per_pixel);
|
||||
ghost->set_duration (_region->nt_length().samples() / samples_per_pixel);
|
||||
|
||||
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
ghost->add_note(i->second);
|
||||
|
@ -1550,9 +1534,7 @@ MidiRegionView::resolve_note (uint8_t note, Temporal::Beats end_time)
|
|||
_active_notes[note]->note()->set_length (end_time - _active_notes[note]->note()->time());
|
||||
|
||||
/* End time is relative to the region being recorded. */
|
||||
const samplepos_t end_time_samples = region_beats_to_region_samples (end_time);
|
||||
|
||||
_active_notes[note]->set_x1 (trackview.editor().sample_to_pixel(end_time_samples));
|
||||
_active_notes[note]->set_x1 (trackview.editor().time_to_pixel (_region->region_beats_to_region_time (end_time)));
|
||||
_active_notes[note]->set_outline_all ();
|
||||
_active_notes[note] = 0;
|
||||
}
|
||||
|
@ -1570,7 +1552,7 @@ MidiRegionView::extend_active_notes()
|
|||
|
||||
for (unsigned i = 0; i < 128; ++i) {
|
||||
if (_active_notes[i]) {
|
||||
_active_notes[i]->set_x1 (trackview.editor().sample_to_pixel(_region->length()));
|
||||
_active_notes[i]->set_x1 (trackview.editor().duration_to_pixels (_region->nt_length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1631,8 +1613,7 @@ MidiRegionView::note_in_region_range (const boost::shared_ptr<NoteType> note, bo
|
|||
const boost::shared_ptr<ARDOUR::MidiRegion> midi_reg = midi_region();
|
||||
|
||||
/* must compare double explicitly as Beats::operator< rounds to ppqn */
|
||||
const bool outside = (note->time() < midi_reg->start_beats() ||
|
||||
note->time() >= midi_reg->start_beats() + midi_reg->length_beats());
|
||||
const bool outside = (timepos_t (note->time()) < _region->nt_start()) || (timepos_t (note->time()) >= _region->nt_start() + _region->nt_length());
|
||||
|
||||
visible = (note->note() >= _current_range_min) &&
|
||||
(note->note() <= _current_range_max);
|
||||
|
@ -1659,14 +1640,11 @@ MidiRegionView::update_note (NoteBase* note, bool update_ghost_regions)
|
|||
void
|
||||
MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
|
||||
{
|
||||
TempoMap& map (trackview.session()->tempo_map());
|
||||
const boost::shared_ptr<ARDOUR::MidiRegion> mr = midi_region();
|
||||
boost::shared_ptr<NoteType> note = ev->note();
|
||||
const timepos_t note_start = _region->source_beats_to_absolute_time (note->time());
|
||||
|
||||
const double session_source_start = _region->quarter_note() - mr->start_beats();
|
||||
const samplepos_t note_start_samples = map.sample_at_quarter_note (note->time() + session_source_start) - _region->position();
|
||||
|
||||
const double x0 = max (0.,trackview.editor().sample_to_pixel (note_start_samples));
|
||||
const double x0 = trackview.editor().time_to_pixel (note_start);
|
||||
double x1;
|
||||
const double y0 = 1 + floor(note_to_y(note->note()));
|
||||
double y1;
|
||||
|
@ -1681,21 +1659,19 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
|
|||
|
||||
/* normal note */
|
||||
|
||||
Temporal::Beats note_end_time = note->end_time();
|
||||
timepos_t note_end (note->end_time());
|
||||
|
||||
if (note->end_time() > mr->start_beats() + mr->length_beats()) {
|
||||
note_end_time = mr->start_beats() + mr->length_beats();
|
||||
if (note_end > mr->nt_start() + mr->nt_length()) {
|
||||
note_end = mr->nt_start() + mr->nt_length();
|
||||
}
|
||||
|
||||
const samplepos_t note_end_samples = map.sample_at_quarter_note (session_source_start + note_end_time) - _region->position();
|
||||
|
||||
x1 = std::max(1., trackview.editor().sample_to_pixel (note_end_samples)) - 1;
|
||||
x1 = std::max(1., trackview.editor().time_to_pixel (note_end)) - 1;
|
||||
|
||||
} else {
|
||||
|
||||
/* nascent note currently being recorded, noteOff has not yet arrived */
|
||||
|
||||
x1 = std::max(1., trackview.editor().sample_to_pixel (_region->length())) - 1;
|
||||
x1 = std::max(1., trackview.editor().duration_to_pixels (_region->nt_length())) - 1;
|
||||
}
|
||||
|
||||
y1 = y0 + std::max(1., floor(note_height()) - 1);
|
||||
|
@ -1735,11 +1711,9 @@ void
|
|||
MidiRegionView::update_hit (Hit* ev, bool update_ghost_regions)
|
||||
{
|
||||
boost::shared_ptr<NoteType> note = ev->note();
|
||||
const timepos_t note_time = _region->source_beats_to_absolute_time (note->time());
|
||||
|
||||
const double note_time_qn = note->time() + (_region->quarter_note() - midi_region()->start_beats());
|
||||
const samplepos_t note_start_samples = trackview.session()->tempo_map().sample_at_quarter_note (note_time_qn) - _region->position();
|
||||
|
||||
const double x = trackview.editor().sample_to_pixel(note_start_samples);
|
||||
const double x = trackview.editor().time_to_pixel(note_time);
|
||||
const double diamond_size = std::max(1., floor(note_height()) - 2.);
|
||||
const double y = 1.5 + floor(note_to_y(note->note())) + diamond_size * .5;
|
||||
|
||||
|
@ -1757,7 +1731,6 @@ MidiRegionView::update_hit (Hit* ev, bool update_ghost_regions)
|
|||
const uint32_t base_col = ev->base_color();
|
||||
ev->set_fill_color(base_col);
|
||||
ev->set_outline_color(ev->calculate_outline(base_col, ev->selected()));
|
||||
|
||||
}
|
||||
|
||||
/** Add a MIDI note to the view (with length).
|
||||
|
@ -1835,12 +1808,11 @@ MidiRegionView::step_add_note (uint8_t channel, uint8_t number, uint8_t velocity
|
|||
|
||||
/* potentially extend region to hold new note */
|
||||
|
||||
samplepos_t end_sample = source_beats_to_absolute_samples (new_note->end_time());
|
||||
samplepos_t region_end = _region->last_sample();
|
||||
timepos_t note_end = _region->source_beats_to_absolute_time (new_note->end_time());
|
||||
timepos_t region_end = _region->nt_last();
|
||||
|
||||
if (end_sample > region_end) {
|
||||
/* XX sets length in beats from audio space. make musical */
|
||||
_region->set_length (end_sample - _region->position(), 0);
|
||||
if (note_end > region_end) {
|
||||
_region->set_length (timecnt_t (note_end.earlier (_region->nt_position()), timepos_t()));
|
||||
}
|
||||
|
||||
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
|
||||
|
@ -1874,8 +1846,8 @@ MidiRegionView::step_sustain (Temporal::Beats beats)
|
|||
void
|
||||
MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch)
|
||||
{
|
||||
samplecnt_t region_samples = source_beats_to_region_samples (patch->time());
|
||||
const double x = trackview.editor().sample_to_pixel (region_samples);
|
||||
timepos_t patch_time = _region->source_beats_to_absolute_time (patch->time());
|
||||
const double x = trackview.editor().time_to_pixel (patch_time);
|
||||
|
||||
double const height = midi_stream_view()->contents_height();
|
||||
|
||||
|
@ -1894,7 +1866,7 @@ MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch)
|
|||
|
||||
if (patch_change->item().width() < _pixel_width) {
|
||||
// Show unless patch change is beyond the region bounds
|
||||
if (region_samples < 0 || region_samples >= _region->length()) {
|
||||
if (patch_time < _region->nt_position() || patch_time >= _region->nt_last()) {
|
||||
patch_change->hide();
|
||||
} else {
|
||||
patch_change->show();
|
||||
|
@ -2019,19 +1991,17 @@ MidiRegionView::change_patch_change (MidiModel::PatchChangePtr old_change, const
|
|||
* MidiTimeAxisView::get_channel_for_add())
|
||||
*/
|
||||
void
|
||||
MidiRegionView::add_patch_change (samplecnt_t t, Evoral::PatchChange<Temporal::Beats> const & patch)
|
||||
MidiRegionView::add_patch_change (timecnt_t const & t, Evoral::PatchChange<Temporal::Beats> const & patch)
|
||||
{
|
||||
string name = _("add patch change");
|
||||
|
||||
trackview.editor().begin_reversible_command (name);
|
||||
MidiModel::PatchChangeDiffCommand* c = _model->new_patch_change_diff_command (name);
|
||||
|
||||
c->add (MidiModel::PatchChangePtr (
|
||||
new Evoral::PatchChange<Temporal::Beats> (
|
||||
absolute_samples_to_source_beats (_region->position() + t),
|
||||
patch.channel(), patch.program(), patch.bank()
|
||||
)
|
||||
)
|
||||
);
|
||||
new Evoral::PatchChange<Temporal::Beats>
|
||||
(_region->source_relative_position (_region->nt_position() + t).beats(),
|
||||
patch.channel(), patch.program(), patch.bank())));
|
||||
|
||||
_model->apply_command (*trackview.session(), c);
|
||||
trackview.editor().commit_reversible_command ();
|
||||
|
@ -2171,11 +2141,11 @@ MidiRegionView::select_all_notes ()
|
|||
}
|
||||
|
||||
void
|
||||
MidiRegionView::select_range (samplepos_t start, samplepos_t end)
|
||||
MidiRegionView::select_range (timepos_t const & start, timepos_t const & end)
|
||||
{
|
||||
PBD::Unwinder<bool> uw (_no_sound_notes, true);
|
||||
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
samplepos_t t = source_beats_to_absolute_samples(i->first->time());
|
||||
timepos_t t = _region->source_beats_to_absolute_time (i->first->time());
|
||||
if (t >= start && t <= end) {
|
||||
add_to_selection (i->second);
|
||||
}
|
||||
|
@ -2403,10 +2373,9 @@ MidiRegionView::update_drag_selection(samplepos_t start, samplepos_t end, double
|
|||
PublicEditor& editor = trackview.editor();
|
||||
|
||||
// Convert to local coordinates
|
||||
const samplepos_t p = _region->position();
|
||||
const double y = midi_view()->y_position();
|
||||
const double x0 = editor.sample_to_pixel(max((samplepos_t)0, start - p));
|
||||
const double x1 = editor.sample_to_pixel(max((samplepos_t)0, end - p));
|
||||
const double x0 = editor.time_to_pixel (max (timepos_t(), _region->region_relative_position (timepos_t (start))));
|
||||
const double x1 = editor.time_to_pixel (max (timepos_t(), _region->region_relative_position (timepos_t (end))));
|
||||
const double y0 = max(0.0, gy0 - y);
|
||||
const double y1 = max(0.0, gy1 - y);
|
||||
|
||||
|
@ -2433,8 +2402,12 @@ MidiRegionView::update_drag_selection(samplepos_t start, samplepos_t end, double
|
|||
const ATracks& atracks = midi_view()->automation_tracks();
|
||||
Selectables selectables;
|
||||
editor.get_selection().clear_points();
|
||||
|
||||
timepos_t st (start);
|
||||
timepos_t et (end);
|
||||
|
||||
for (ATracks::const_iterator a = atracks.begin(); a != atracks.end(); ++a) {
|
||||
a->second->get_selectables(start, end, gy0, gy1, selectables);
|
||||
a->second->get_selectables (st, et, gy0, gy1, selectables);
|
||||
for (Selectables::const_iterator s = selectables.begin(); s != selectables.end(); ++s) {
|
||||
ControlPoint* cp = dynamic_cast<ControlPoint*>(*s);
|
||||
if (cp) {
|
||||
|
@ -2531,7 +2504,7 @@ MidiRegionView::earliest_in_selection ()
|
|||
}
|
||||
|
||||
void
|
||||
MidiRegionView::move_selection(double dx_qn, double dy, double cumulative_dy)
|
||||
MidiRegionView::move_selection(Temporal::Beats const & dx_qn, double dy, double cumulative_dy)
|
||||
{
|
||||
typedef vector<boost::shared_ptr<NoteType> > PossibleChord;
|
||||
Editor* editor = dynamic_cast<Editor*> (&trackview.editor());
|
||||
|
@ -2544,8 +2517,9 @@ MidiRegionView::move_selection(double dx_qn, double dy, double cumulative_dy)
|
|||
if (n->note()->time() == earliest) {
|
||||
to_play.push_back (n->note());
|
||||
}
|
||||
double const note_time_qn = session_relative_qn (n->note()->time());
|
||||
Temporal::Beats const note_time_qn = _region->source_beats_to_absolute_beats (n->note()->time());
|
||||
double dx = 0.0;
|
||||
|
||||
if (midi_view()->note_mode() == Sustained) {
|
||||
dx = editor->sample_to_pixel_unrounded (tmap.sample_at_quarter_note (note_time_qn + dx_qn))
|
||||
- n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
|
||||
|
@ -2640,8 +2614,10 @@ MidiRegionView::move_copies (Temporal::Beats const & dx_qn, double dy, double c
|
|||
if (n->note()->time() == earliest) {
|
||||
to_play.push_back (n->note());
|
||||
}
|
||||
Temporal::Beats const note_time_qn = Temporal::Beats::from_double (session_relative_qn (n->note()->time()));
|
||||
|
||||
Temporal::Beats const note_time_qn = _region->source_beats_to_absolute_beats (n->note()->time());
|
||||
double dx = 0.0;
|
||||
|
||||
if (midi_view()->note_mode() == Sustained) {
|
||||
dx = editor->sample_to_pixel_unrounded (tmap.sample_at_quarter_note (note_time_qn + dx_qn))
|
||||
- n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
|
||||
|
@ -2801,13 +2777,13 @@ MidiRegionView::note_dropped(NoteBase *, Temporal::Beats const & d_qn, int8_t dn
|
|||
/** @param x Pixel relative to the region position.
|
||||
* @param ensure_snap defaults to false. true = snap always, ignoring snap mode and magnetic snap.
|
||||
* Used for inverting the snap logic with key modifiers and snap delta calculation.
|
||||
* @return Snapped sample relative to the region position.
|
||||
* @return Snapped time relative to the region position.
|
||||
*/
|
||||
samplepos_t
|
||||
MidiRegionView::snap_pixel_to_sample(double x, bool ensure_snap)
|
||||
timepos_t
|
||||
MidiRegionView::snap_pixel_to_time (double x, bool ensure_snap)
|
||||
{
|
||||
PublicEditor& editor (trackview.editor());
|
||||
return snap_sample_to_sample (editor.pixel_to_sample (x), ensure_snap).sample;
|
||||
return snap_region_time_to_region_time (timepos_t (editor.pixel_to_sample (x)), ensure_snap);
|
||||
}
|
||||
|
||||
/** @param x Pixel relative to the region position.
|
||||
|
@ -2817,21 +2793,20 @@ MidiRegionView::snap_pixel_to_sample(double x, bool ensure_snap)
|
|||
double
|
||||
MidiRegionView::snap_to_pixel(double x, bool ensure_snap)
|
||||
{
|
||||
return (double) trackview.editor().sample_to_pixel(snap_pixel_to_sample(x, ensure_snap));
|
||||
return (double) trackview.editor().time_to_pixel(snap_pixel_to_time(x, ensure_snap));
|
||||
}
|
||||
|
||||
double
|
||||
MidiRegionView::get_position_pixels()
|
||||
{
|
||||
samplepos_t region_sample = get_position();
|
||||
return trackview.editor().sample_to_pixel(region_sample);
|
||||
return trackview.editor().time_to_pixel(get_position());
|
||||
}
|
||||
|
||||
double
|
||||
MidiRegionView::get_end_position_pixels()
|
||||
{
|
||||
samplepos_t sample = get_position() + get_duration ();
|
||||
return trackview.editor().sample_to_pixel(sample);
|
||||
const timepos_t end = get_position() + get_duration ();
|
||||
return trackview.editor().time_to_pixel (end);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2886,7 +2861,6 @@ MidiRegionView::begin_resizing (bool /*at_front*/)
|
|||
void
|
||||
MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_x, bool relative, double snap_delta, bool with_snap)
|
||||
{
|
||||
TempoMap& tmap (trackview.session()->tempo_map());
|
||||
bool cursor_set = false;
|
||||
bool const ensure_snap = trackview.editor().snap_mode () != SnapMagnetic;
|
||||
|
||||
|
@ -2915,8 +2889,8 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
|
|||
*/
|
||||
current_x = 0;
|
||||
}
|
||||
if (current_x > trackview.editor().sample_to_pixel(_region->length())) {
|
||||
current_x = trackview.editor().sample_to_pixel(_region->length());
|
||||
if (current_x > trackview.editor().duration_to_pixels (_region->nt_length())) {
|
||||
current_x = trackview.editor().duration_to_pixels (_region->nt_length());
|
||||
}
|
||||
|
||||
if (at_front) {
|
||||
|
@ -2935,47 +2909,49 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
|
|||
resize_rect->set_x0 (canvas_note->x0());
|
||||
}
|
||||
|
||||
|
||||
if (!cursor_set) {
|
||||
/* Convert snap delta from pixels to beats. */
|
||||
samplepos_t snap_delta_samps = trackview.editor().pixel_to_sample (snap_delta);
|
||||
double snap_delta_beats = 0.0;
|
||||
int sign = 1;
|
||||
|
||||
|
||||
/* negative beat offsets aren't allowed */
|
||||
if (snap_delta_samps > 0) {
|
||||
snap_delta_beats = region_samples_to_region_beats_double (snap_delta_samps);
|
||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (snap_delta_samps, _region->nt_position()));
|
||||
} else if (snap_delta_samps < 0) {
|
||||
snap_delta_beats = region_samples_to_region_beats_double (- snap_delta_samps);
|
||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (-snap_delta_samps, _region->nt_position()));
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
double snapped_x;
|
||||
int32_t divisions = 0;
|
||||
timepos_t snapped_x;
|
||||
|
||||
if (with_snap) {
|
||||
snapped_x = snap_pixel_to_sample (current_x, ensure_snap);
|
||||
divisions = trackview.editor().get_grid_music_divisions (0);
|
||||
snapped_x = snap_pixel_to_time (current_x, ensure_snap); /* units depend on snap settings */
|
||||
} else {
|
||||
snapped_x = trackview.editor ().pixel_to_sample (current_x);
|
||||
snapped_x = trackview.editor ().pixel_to_sample (current_x); /* samples */
|
||||
}
|
||||
|
||||
const Temporal::Beats beats = Temporal::Beats::from_double (tmap.exact_beat_at_sample (snapped_x + midi_region()->position(), divisions) - midi_region()->beat()) + midi_region()->start_beats();
|
||||
|
||||
#warning NUTEMPO need new tempo map API
|
||||
//TempoMap& tmap (trackview.session()->tempo_map());
|
||||
//const timepos_t abs_beats (tmap.quarter_note_at (snapped_x));
|
||||
const timepos_t abs_beats;
|
||||
const Temporal::Beats beats = _region->absolute_time_to_source_beats (abs_beats);
|
||||
Temporal::Beats len = Temporal::Beats();
|
||||
|
||||
if (at_front) {
|
||||
if (beats < canvas_note->note()->end_time()) {
|
||||
len = canvas_note->note()->time() - beats + (sign * snap_delta_beats);
|
||||
len = canvas_note->note()->time() - beats + (snap_delta_beats * sign);
|
||||
len += canvas_note->note()->length();
|
||||
}
|
||||
} else {
|
||||
if (beats >= canvas_note->note()->time()) {
|
||||
len = beats - canvas_note->note()->time() - (sign * snap_delta_beats);
|
||||
len = beats - canvas_note->note()->time() - (snap_delta_beats * sign);
|
||||
}
|
||||
}
|
||||
|
||||
/* minimum length resulting from a trim is 1 tick */
|
||||
len = std::max (Temporal::Beats (0,1), len);
|
||||
len = std::max (Temporal::Beats::from_double (1 / 512.0), len);
|
||||
|
||||
char buf[16];
|
||||
/* represent as float frac to help out the user */
|
||||
|
@ -2984,7 +2960,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
|
|||
|
||||
cursor_set = true;
|
||||
|
||||
trackview.editor().set_snapped_cursor_position ( snapped_x + midi_region()->position() );
|
||||
trackview.editor().set_snapped_cursor_position ((snapped_x + midi_region()->nt_position()).samples());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3030,41 +3006,41 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
|
|||
if (current_x < 0) {
|
||||
current_x = 0;
|
||||
}
|
||||
if (current_x > trackview.editor().sample_to_pixel(_region->length())) {
|
||||
current_x = trackview.editor().sample_to_pixel(_region->length());
|
||||
|
||||
if (current_x > trackview.editor().duration_to_pixels (_region->nt_length())) {
|
||||
current_x = trackview.editor().duration_to_pixels (_region->nt_length());
|
||||
}
|
||||
|
||||
/* Convert snap delta from pixels to beats with sign. */
|
||||
samplepos_t snap_delta_samps = trackview.editor().pixel_to_sample (snap_delta);
|
||||
double snap_delta_beats = 0.0;
|
||||
Temporal::Beats snap_delta_beats;
|
||||
int sign = 1;
|
||||
|
||||
if (snap_delta_samps > 0) {
|
||||
snap_delta_beats = region_samples_to_region_beats_double (snap_delta_samps);
|
||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (snap_delta_samps, _region->nt_position()));
|
||||
} else if (snap_delta_samps < 0) {
|
||||
snap_delta_beats = region_samples_to_region_beats_double ( - snap_delta_samps);
|
||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (-snap_delta_samps, _region->nt_position()));
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
uint32_t divisions = 0;
|
||||
/* Convert the new x position to a sample within the source */
|
||||
samplepos_t current_fr;
|
||||
timepos_t current_time;
|
||||
if (with_snap) {
|
||||
current_fr = snap_pixel_to_sample (current_x, ensure_snap);
|
||||
divisions = trackview.editor().get_grid_music_divisions (0);
|
||||
current_time = snap_pixel_to_time (current_x, ensure_snap);
|
||||
} else {
|
||||
current_fr = trackview.editor().pixel_to_sample (current_x);
|
||||
current_time = trackview.editor().pixel_to_sample (current_x);
|
||||
}
|
||||
|
||||
/* and then to beats */
|
||||
const double e_qaf = tmap.exact_qn_at_sample (current_fr + midi_region()->position(), divisions);
|
||||
const double quarter_note_start = _region->quarter_note() - midi_region()->start_beats();
|
||||
const Temporal::Beats x_beats = Temporal::Beats::from_double (e_qaf - quarter_note_start);
|
||||
#warning NUTEMPO need new tempo map
|
||||
//const timepos_t abs_beats (tmap.quarter_note_at (current_time));
|
||||
const timepos_t abs_beats;
|
||||
const Temporal::Beats x_beats = _region->absolute_time_to_source_beats (abs_beats);
|
||||
|
||||
if (at_front && x_beats < canvas_note->note()->end_time()) {
|
||||
const Temporal::Beats new_start = x_beats - (sign * snap_delta_beats);
|
||||
note_diff_add_change (canvas_note, MidiModel::NoteDiffCommand::StartTime, new_start);
|
||||
Temporal::Beats len = canvas_note->note()->end_time() - new_start;
|
||||
note_diff_add_change (canvas_note, MidiModel::NoteDiffCommand::StartTime, x_beats - (snap_delta_beats * sign));
|
||||
Temporal::Beats len = canvas_note->note()->time() - x_beats + (snap_delta_beats * sign);
|
||||
len += canvas_note->note()->length();
|
||||
|
||||
if (!!len) {
|
||||
note_diff_add_change (canvas_note, MidiModel::NoteDiffCommand::Length, len);
|
||||
|
@ -3072,7 +3048,7 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
|
|||
}
|
||||
|
||||
if (!at_front) {
|
||||
Temporal::Beats len = std::max (Temporal::Beats(0, 1), x_beats - canvas_note->note()->time() - (sign * snap_delta_beats));
|
||||
Temporal::Beats len = std::max (Temporal::Beats (0, 1), x_beats - canvas_note->note()->time() - (snap_delta_beats * sign));
|
||||
note_diff_add_change (canvas_note, MidiModel::NoteDiffCommand::Length, len);
|
||||
}
|
||||
|
||||
|
@ -3363,7 +3339,7 @@ MidiRegionView::change_note_lengths (bool fine, bool shorter, Temporal::Beats de
|
|||
delta = Temporal::Beats::ticks (Temporal::ticks_per_beat / 128);
|
||||
} else {
|
||||
/* grab the current grid distance */
|
||||
delta = get_grid_beats(_region->position());
|
||||
delta = get_grid_beats (_region->nt_position());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3401,16 +3377,16 @@ MidiRegionView::nudge_notes (bool forward, bool fine)
|
|||
into a vector and sort before using the first one.
|
||||
*/
|
||||
|
||||
const samplepos_t ref_point = source_beats_to_absolute_samples ((*(_selection.begin()))->note()->time());
|
||||
const timepos_t ref_point = _region->source_beats_to_absolute_time ((*(_selection.begin()))->note()->time());
|
||||
Temporal::Beats delta;
|
||||
|
||||
if (trackview.editor().snap_mode() == Editing::SnapOff) {
|
||||
|
||||
/* grid is off - use nudge distance */
|
||||
|
||||
samplepos_t unused;
|
||||
const samplecnt_t distance = trackview.editor().get_nudge_distance (ref_point, unused);
|
||||
delta = region_samples_to_region_beats (fabs ((double)distance));
|
||||
timecnt_t unused;
|
||||
const timecnt_t distance = trackview.editor().get_nudge_distance (ref_point, unused);
|
||||
delta = _region->region_distance_to_region_beats (timecnt_t (distance.beats(), _region->nt_position()));
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -3664,7 +3640,7 @@ MidiRegionView::selection_as_cut_buffer () const
|
|||
|
||||
/** This method handles undo */
|
||||
bool
|
||||
MidiRegionView::paste (samplepos_t pos, const ::Selection& selection, PasteContext& ctx, const int32_t sub_num)
|
||||
MidiRegionView::paste (timepos_t const & pos, const ::Selection& selection, PasteContext& ctx)
|
||||
{
|
||||
bool commit = false;
|
||||
// Paste notes, if available
|
||||
|
@ -3681,7 +3657,7 @@ MidiRegionView::paste (samplepos_t pos, const ::Selection& selection, PasteConte
|
|||
typedef RouteTimeAxisView::AutomationTracks ATracks;
|
||||
const ATracks& atracks = midi_view()->automation_tracks();
|
||||
for (ATracks::const_iterator a = atracks.begin(); a != atracks.end(); ++a) {
|
||||
if (a->second->paste(pos, selection, ctx, sub_num)) {
|
||||
if (a->second->paste(pos, selection, ctx)) {
|
||||
if(!commit) {
|
||||
trackview.editor().begin_reversible_command (Operations::paste);
|
||||
}
|
||||
|
@ -3697,7 +3673,7 @@ MidiRegionView::paste (samplepos_t pos, const ::Selection& selection, PasteConte
|
|||
|
||||
/** This method handles undo */
|
||||
void
|
||||
MidiRegionView::paste_internal (samplepos_t pos, unsigned paste_count, float times, const MidiCutBuffer& mcb)
|
||||
MidiRegionView::paste_internal (timepos_t const & pos, unsigned paste_count, float times, const MidiCutBuffer& mcb)
|
||||
{
|
||||
if (mcb.empty()) {
|
||||
return;
|
||||
|
@ -3710,14 +3686,14 @@ MidiRegionView::paste_internal (samplepos_t pos, unsigned paste_count, float tim
|
|||
const Temporal::Beats last_time = (*mcb.notes().rbegin())->end_time();
|
||||
const Temporal::Beats duration = last_time - first_time;
|
||||
const Temporal::Beats snap_duration = duration.snap_to(snap_beats);
|
||||
const Temporal::Beats paste_offset = snap_duration * paste_count;
|
||||
const Temporal::Beats quarter_note = absolute_samples_to_source_beats(pos) + paste_offset;
|
||||
Temporal::Beats end_point = Temporal::Beats();
|
||||
const Temporal::Beats paste_offset = snap_duration * int32_t (paste_count);
|
||||
const Temporal::Beats quarter_note = _region->absolute_time_to_source_beats (pos) + paste_offset;
|
||||
Temporal::Beats end_point;
|
||||
|
||||
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste data spans from %1 to %2 (%3) ; paste pos beats = %4 (based on %5 - %6)\n",
|
||||
first_time,
|
||||
last_time,
|
||||
duration, pos, _region->position(),
|
||||
duration, pos, _region->nt_position(),
|
||||
quarter_note));
|
||||
|
||||
for (int n = 0; n < (int) times; ++n) {
|
||||
|
@ -3737,16 +3713,16 @@ MidiRegionView::paste_internal (samplepos_t pos, unsigned paste_count, float tim
|
|||
|
||||
/* if we pasted past the current end of the region, extend the region */
|
||||
|
||||
samplepos_t end_sample = source_beats_to_absolute_samples (end_point);
|
||||
samplepos_t region_end = _region->position() + _region->length() - 1;
|
||||
timepos_t end = _region->source_beats_to_absolute_time (end_point);
|
||||
timepos_t region_end = _region->nt_last();
|
||||
|
||||
if (end_sample > region_end) {
|
||||
if (end > region_end) {
|
||||
|
||||
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste extended region from %1 to %2\n", region_end, end_sample));
|
||||
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste extended region from %1 to %2\n", region_end, end));
|
||||
|
||||
_region->clear_changes ();
|
||||
/* we probably need to get the snap modifier somehow to make this correct for non-musical use */
|
||||
_region->set_length (end_sample - _region->position(), trackview.editor().get_grid_music_divisions (0));
|
||||
_region->set_length (_region->nt_position().distance (end));
|
||||
trackview.session()->add_command (new StatefulDiffCommand (_region));
|
||||
}
|
||||
|
||||
|
@ -3903,12 +3879,11 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
|
|||
|
||||
samplepos_t const unsnapped_sample = editor.pixel_to_sample (x);
|
||||
|
||||
const int32_t divisions = editor.get_grid_music_divisions (state);
|
||||
const bool shift_snap = midi_view()->note_mode() != Percussive;
|
||||
const Temporal::Beats snapped_beats = snap_sample_to_grid_underneath (unsnapped_sample, divisions, shift_snap);
|
||||
const Temporal::Beats snapped_beats = snap_sample_to_grid_underneath (unsnapped_sample, shift_snap);
|
||||
|
||||
/* prevent Percussive mode from displaying a ghost hit at region end */
|
||||
if (!shift_snap && snapped_beats >= midi_region()->start_beats() + midi_region()->length_beats()) {
|
||||
if (!shift_snap && snapped_beats >= _region->nt_start().beats() + _region->nt_length().beats()) {
|
||||
_ghost_note->hide();
|
||||
hide_verbose_cursor ();
|
||||
return;
|
||||
|
@ -3927,14 +3902,13 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
|
|||
_ghost_note->show();
|
||||
|
||||
/* calculate time in beats relative to start of source */
|
||||
const Temporal::Beats length = get_grid_beats(unsnapped_sample + _region->position());
|
||||
const Temporal::Beats length = get_grid_beats (_region->nt_position() + timepos_t (unsnapped_sample));
|
||||
|
||||
_ghost_note->note()->set_time (snapped_beats);
|
||||
_ghost_note->note()->set_length (length);
|
||||
_ghost_note->note()->set_note (y_to_note (y));
|
||||
_ghost_note->note()->set_channel (mtv->get_channel_for_add ());
|
||||
_ghost_note->note()->set_velocity (get_velocity_for_add (snapped_beats));
|
||||
/* the ghost note does not appear in ghost regions, so pass false in here */
|
||||
update_note (_ghost_note, false);
|
||||
|
||||
show_verbose_cursor (_ghost_note->note ());
|
||||
|
@ -4073,7 +4047,7 @@ MidiRegionView::move_step_edit_cursor (Temporal::Beats pos)
|
|||
_step_edit_cursor_position = pos;
|
||||
|
||||
if (_step_edit_cursor) {
|
||||
double pixel = trackview.editor().sample_to_pixel (region_beats_to_region_samples (pos));
|
||||
double pixel = trackview.editor().time_to_pixel (_region->region_beats_to_region_time (pos));
|
||||
_step_edit_cursor->set_x0 (pixel);
|
||||
set_step_edit_cursor_width (_step_edit_cursor_width);
|
||||
}
|
||||
|
@ -4093,10 +4067,9 @@ MidiRegionView::set_step_edit_cursor_width (Temporal::Beats beats)
|
|||
_step_edit_cursor_width = beats;
|
||||
|
||||
if (_step_edit_cursor) {
|
||||
_step_edit_cursor->set_x1 (_step_edit_cursor->x0()
|
||||
+ trackview.editor().sample_to_pixel (
|
||||
region_beats_to_region_samples (_step_edit_cursor_position + beats)
|
||||
- region_beats_to_region_samples (_step_edit_cursor_position)));
|
||||
_step_edit_cursor->set_x1 (_step_edit_cursor->x0() + trackview.editor().duration_to_pixels (
|
||||
_region->region_beats_to_region_time (_step_edit_cursor_position).distance
|
||||
(_region->region_beats_to_region_time (_step_edit_cursor_position + beats))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4134,9 +4107,12 @@ MidiRegionView::data_recorded (boost::weak_ptr<MidiSource> w)
|
|||
}
|
||||
}
|
||||
|
||||
/* convert from session samples to source beats */
|
||||
Temporal::Beats const time_beats = _source_relative_time_converter.from(
|
||||
ev.time() - src->natural_position() + _region->start());
|
||||
/* ev.time() is in MidiBuffer::TimeType i.e. samples
|
||||
|
||||
we want to convert to beats relative to source start.
|
||||
*/
|
||||
|
||||
Temporal::Beats const time_beats = _region->absolute_time_to_source_beats (timepos_t (ev.time()));
|
||||
|
||||
if (ev.type() == MIDI_CMD_NOTE_ON) {
|
||||
|
||||
|
@ -4174,7 +4150,7 @@ MidiRegionView::trim_front_starting ()
|
|||
void
|
||||
MidiRegionView::trim_front_ending ()
|
||||
{
|
||||
if (_region->start() < 0) {
|
||||
if (_region->nt_start().negative()) {
|
||||
/* Trim drag made start time -ve; fix this */
|
||||
midi_region()->fix_negative_start ();
|
||||
}
|
||||
|
@ -4183,7 +4159,7 @@ MidiRegionView::trim_front_ending ()
|
|||
void
|
||||
MidiRegionView::edit_patch_change (PatchChange* pc)
|
||||
{
|
||||
PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY, true);
|
||||
PatchChangeDialog d (trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY, true, true, _region);
|
||||
|
||||
int response = d.run();
|
||||
|
||||
|
@ -4294,25 +4270,32 @@ MidiRegionView::get_velocity_for_add (MidiModel::TimeType time) const
|
|||
* @return beat duration of p snapped to the grid subdivision underneath it.
|
||||
*/
|
||||
Temporal::Beats
|
||||
MidiRegionView::snap_sample_to_grid_underneath (samplepos_t p, int32_t divisions, bool shift_snap) const
|
||||
MidiRegionView::snap_sample_to_grid_underneath (samplepos_t p, bool shift_snap) const
|
||||
{
|
||||
TempoMap& map (trackview.session()->tempo_map());
|
||||
double eqaf = map.exact_qn_at_sample (p + _region->position(), divisions);
|
||||
#warning NUTEMPO new tempo map API required
|
||||
#if 0
|
||||
Temporal::TempoMap& map (trackview.session()->tempo_map());
|
||||
Temporal::Beats eqaf = map.quarter_note_at (p + _region->position_sample());
|
||||
|
||||
if (divisions != 0 && shift_snap) {
|
||||
const Temporal::Beats qaf = Temporal::Beats::from_double (map.quarter_note_at_sample (p + _region->position()));
|
||||
|
||||
if (shift_snap) {
|
||||
const Temporal::Beats qaf = map.quarter_note_at (p + _region->position_sample());
|
||||
/* Hack so that we always snap to the note that we are over, instead of snapping
|
||||
to the next one if we're more than halfway through the one we're over.
|
||||
*/
|
||||
const Temporal::Beats grid_beats = get_grid_beats (p + _region->position());
|
||||
const double rem = eqaf - qaf;
|
||||
if (rem >= 0.0) {
|
||||
const Temporal::Beats grid_beats = get_grid_beats (p + _region->position_sample());
|
||||
const Temporal::Beats rem = eqaf - qaf;
|
||||
|
||||
if (rem >= Temporal::Beats()) {
|
||||
eqaf -= grid_beats;
|
||||
}
|
||||
}
|
||||
const double session_start_off = _region->quarter_note() - midi_region()->start_beats();
|
||||
|
||||
return Temporal::Beats::from_double (eqaf - session_start_off);
|
||||
const timepos_t e (eqaf);
|
||||
|
||||
return _region->absolute_time_to_source_beats (e);
|
||||
#endif
|
||||
return Temporal::Beats ();
|
||||
}
|
||||
|
||||
ChannelMode
|
||||
|
@ -4331,14 +4314,16 @@ MidiRegionView::get_selected_channels () const
|
|||
|
||||
|
||||
Temporal::Beats
|
||||
MidiRegionView::get_grid_beats(samplepos_t pos) const
|
||||
MidiRegionView::get_grid_beats (timepos_t const & pos) const
|
||||
{
|
||||
PublicEditor& editor = trackview.editor();
|
||||
bool success = false;
|
||||
Temporal::Beats beats = editor.get_grid_type_as_beats (success, pos);
|
||||
|
||||
if (!success) {
|
||||
beats = Temporal::Beats (1, 0);
|
||||
}
|
||||
|
||||
return beats;
|
||||
}
|
||||
uint8_t
|
||||
|
@ -4363,8 +4348,3 @@ MidiRegionView::note_to_y(uint8_t note) const
|
|||
return contents_height() - (note + 1 - _current_range_min) * note_height() + 1;
|
||||
}
|
||||
|
||||
double
|
||||
MidiRegionView::session_relative_qn (double qn) const
|
||||
{
|
||||
return qn + (region()->quarter_note() - midi_region()->start_beats());
|
||||
}
|
||||
|
|
|
@ -128,8 +128,8 @@ public:
|
|||
void resolve_note(uint8_t note_num, Temporal::Beats end_time);
|
||||
|
||||
void cut_copy_clear (Editing::CutCopyOp);
|
||||
bool paste (samplepos_t pos, const ::Selection& selection, PasteContext& ctx, const int32_t sub_num);
|
||||
void paste_internal (samplepos_t pos, unsigned paste_count, float times, const MidiCutBuffer&);
|
||||
bool paste (Temporal::timepos_t const & pos, const ::Selection& selection, PasteContext& ctx);
|
||||
void paste_internal (Temporal::timepos_t const & pos, unsigned paste_count, float times, const MidiCutBuffer&);
|
||||
|
||||
void add_canvas_patch_change (ARDOUR::MidiModel::PatchChangePtr patch);
|
||||
void remove_canvas_patch_change (PatchChange* pc);
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
void change_patch_change (PatchChange& old_patch, const MIDI::Name::PatchPrimaryKey& new_patch);
|
||||
void change_patch_change (ARDOUR::MidiModel::PatchChangePtr, Evoral::PatchChange<Temporal::Beats> const &);
|
||||
|
||||
void add_patch_change (samplecnt_t, Evoral::PatchChange<Temporal::Beats> const &);
|
||||
void add_patch_change (Temporal::timecnt_t const &, Evoral::PatchChange<Temporal::Beats> const &);
|
||||
void move_patch_change (PatchChange &, Temporal::Beats);
|
||||
void delete_patch_change (PatchChange *);
|
||||
void edit_patch_change (PatchChange *);
|
||||
|
@ -205,12 +205,12 @@ public:
|
|||
void delete_note (boost::shared_ptr<NoteType>);
|
||||
size_t selection_size() { return _selection.size(); }
|
||||
void select_all_notes ();
|
||||
void select_range(samplepos_t start, samplepos_t end);
|
||||
void select_range(Temporal::timepos_t const & start, Temporal::timepos_t const & end);
|
||||
void invert_selection ();
|
||||
void extend_selection ();
|
||||
|
||||
Temporal::Beats earliest_in_selection ();
|
||||
void move_selection(double dx, double dy, double cumulative_dy);
|
||||
void move_selection(Temporal::Beats const & dx, double dy, double cumulative_dy);
|
||||
void note_dropped (NoteBase* ev, Temporal::Beats const & d_qn, int8_t d_note, bool copy);
|
||||
NoteBase* copy_selection (NoteBase* primary);
|
||||
void move_copies(Temporal::Beats const & dx_qn, double dy, double cumulative_dy);
|
||||
|
@ -450,10 +450,6 @@ public:
|
|||
typedef boost::unordered_map<ARDOUR::MidiModel::constSysExPtr, boost::shared_ptr<SysEx> > SysExes;
|
||||
typedef std::vector<NoteBase*> CopyDragEvents;
|
||||
|
||||
ARDOUR::BeatsSamplesConverter _region_relative_time_converter;
|
||||
ARDOUR::BeatsSamplesConverter _source_relative_time_converter;
|
||||
ARDOUR::BeatsSamplesConverter _region_relative_time_converter_double;
|
||||
|
||||
boost::shared_ptr<ARDOUR::MidiModel> _model;
|
||||
Events _events;
|
||||
CopyDragEvents _copy_drag_events;
|
||||
|
@ -533,7 +529,7 @@ public:
|
|||
void data_recorded (boost::weak_ptr<ARDOUR::MidiSource>);
|
||||
|
||||
/** Get grid type as beats, or default to 1 if not snapped to beats. */
|
||||
Temporal::Beats get_grid_beats(samplepos_t pos) const;
|
||||
Temporal::Beats get_grid_beats(Temporal::timepos_t const & pos) const;
|
||||
|
||||
void remove_ghost_note ();
|
||||
void mouse_mode_changed ();
|
||||
|
@ -553,7 +549,7 @@ public:
|
|||
Gtkmm2ext::Color _patch_change_outline;
|
||||
Gtkmm2ext::Color _patch_change_fill;
|
||||
|
||||
Temporal::Beats snap_sample_to_grid_underneath (samplepos_t p, int32_t divisions, bool shift_snap) const;
|
||||
Temporal::Beats snap_sample_to_grid_underneath (samplepos_t p, bool shift_snap) const;
|
||||
|
||||
PBD::ScopedConnection _mouse_mode_connection;
|
||||
|
||||
|
|
|
@ -643,20 +643,20 @@ ClockOption::set_state_from_config ()
|
|||
Timecode::Time TC;
|
||||
samplepos_t when;
|
||||
if (!Timecode::parse_timecode_format(_get(), TC)) {
|
||||
_clock.set (0, true);
|
||||
_clock.set (timepos_t (0), true);
|
||||
}
|
||||
TC.rate = _session->samples_per_timecode_frame();
|
||||
TC.drop = _session->timecode_drop_frames();
|
||||
_session->timecode_to_sample(TC, when, false, false);
|
||||
if (TC.negative) { when=-when; }
|
||||
_clock.set (when, true);
|
||||
_clock.set (timepos_t (when), true);
|
||||
}
|
||||
|
||||
void
|
||||
ClockOption::save_clock_time ()
|
||||
{
|
||||
Timecode::Time TC;
|
||||
_session->sample_to_timecode(_clock.current_time(), TC, false, false);
|
||||
_session->sample_to_timecode (_clock.current_time().samples(), TC, false, false);
|
||||
_set (Timecode::timecode_format_time(TC));
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ using namespace Gtkmm2ext;
|
|||
|
||||
/** @param tc If non-0, a time converter for this patch change. If 0, time control will be desensitized */
|
||||
PatchChangeDialog::PatchChangeDialog (
|
||||
const ARDOUR::BeatsSamplesConverter* tc,
|
||||
ARDOUR::Session* session,
|
||||
Evoral::PatchChange<Temporal::Beats> const& patch,
|
||||
ARDOUR::InstrumentInfo& info,
|
||||
|
|
|
@ -42,7 +42,6 @@ class PatchChangeDialog : public ArdourDialog
|
|||
{
|
||||
public:
|
||||
PatchChangeDialog (
|
||||
const ARDOUR::BeatsSamplesConverter*,
|
||||
ARDOUR::Session*,
|
||||
Evoral::PatchChange<Temporal::Beats> const&,
|
||||
ARDOUR::InstrumentInfo&,
|
||||
|
|
|
@ -210,6 +210,10 @@ public:
|
|||
virtual samplepos_t playhead_cursor_sample () const = 0;
|
||||
virtual double sample_to_pixel (samplepos_t sample) const = 0;
|
||||
virtual double sample_to_pixel_unrounded (samplepos_t sample) const = 0;
|
||||
virtual double time_to_pixel (Temporal::timepos_t const &) const = 0;
|
||||
virtual double time_to_pixel_unrounded (Temporal::timepos_t const &) const = 0;
|
||||
virtual double duration_to_pixels (Temporal::timecnt_t const &) const = 0;
|
||||
virtual double duration_to_pixels_unrounded (Temporal::timecnt_t const &) const = 0;
|
||||
|
||||
virtual Selection& get_selection () const = 0;
|
||||
virtual bool get_selection_extents (samplepos_t &start, samplepos_t &end) const = 0;
|
||||
|
@ -354,7 +358,7 @@ public:
|
|||
virtual void toggle_meter_updating() = 0;
|
||||
virtual void split_regions_at (Temporal::timepos_t const &, RegionSelection&) = 0;
|
||||
virtual void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false) = 0;
|
||||
virtual void mouse_add_new_marker (Temporal::timepos_t const & where, bool is_cd=false) = 0;
|
||||
virtual void mouse_add_new_marker (Temporal::timepos_t where, bool is_cd=false) = 0;
|
||||
virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
|
||||
virtual void add_to_idle_resize (TimeAxisView*, int32_t) = 0;
|
||||
virtual Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) = 0;
|
||||
|
@ -512,8 +516,8 @@ public:
|
|||
virtual void build_region_boundary_cache () = 0;
|
||||
virtual void mark_region_boundary_cache_dirty () = 0;
|
||||
|
||||
virtual void mouse_add_new_tempo_event (samplepos_t where) = 0;
|
||||
virtual void mouse_add_new_meter_event (samplepos_t where) = 0;
|
||||
virtual void mouse_add_new_tempo_event (Temporal::timepos_t where) = 0;
|
||||
virtual void mouse_add_new_meter_event (Temporal::timepos_t where) = 0;
|
||||
virtual void edit_tempo_section (ARDOUR::TempoSection*) = 0;
|
||||
virtual void edit_meter_section (ARDOUR::MeterSection*) = 0;
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ RegionEditor::RegionEditor (Session* s, boost::shared_ptr<Region> r)
|
|||
start_label.set_text (_("File start:"));
|
||||
_sources_label.set_name ("RegionEditorLabel");
|
||||
|
||||
if (_region->n_channels() > 1) {
|
||||
if (_region->sources().size() > 1) {
|
||||
_sources_label.set_text (_("Sources:"));
|
||||
} else {
|
||||
_sources_label.set_text (_("Source:"));
|
||||
|
@ -174,7 +174,7 @@ RegionEditor::RegionEditor (Session* s, boost::shared_ptr<Region> r)
|
|||
|
||||
set_title (string_compose (_("Region '%1'"), _region->name()));
|
||||
|
||||
for (uint32_t i = 0; i < _region->n_channels(); ++i) {
|
||||
for (uint32_t i = 0; i < _region->sources().size(); ++i) {
|
||||
_sources.append_text (_region->source(i)->name());
|
||||
}
|
||||
|
||||
|
@ -321,13 +321,13 @@ RegionEditor::end_clock_changed ()
|
|||
PublicEditor::instance().commit_reversible_command ();
|
||||
}
|
||||
|
||||
end_clock.set (_region->position() + _region->length() - 1, true);
|
||||
end_clock.set (_region->nt_last(), true);
|
||||
}
|
||||
|
||||
void
|
||||
RegionEditor::length_clock_changed ()
|
||||
{
|
||||
samplecnt_t samples = length_clock.current_time();
|
||||
timecnt_t len = length_clock.current_duration();
|
||||
bool in_command = false;
|
||||
boost::shared_ptr<Playlist> pl = _region->playlist();
|
||||
|
||||
|
@ -336,7 +336,7 @@ RegionEditor::length_clock_changed ()
|
|||
in_command = true;
|
||||
|
||||
_region->clear_changes ();
|
||||
_region->trim_end (_region->position() + samples - 1);
|
||||
_region->trim_end (_region->nt_position() + len.decrement());
|
||||
_session->add_command(new StatefulDiffCommand (_region));
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ RegionEditor::length_clock_changed ()
|
|||
PublicEditor::instance().commit_reversible_command ();
|
||||
}
|
||||
|
||||
length_clock.set (_region->length());
|
||||
length_clock.set_duration (_region->nt_length());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -369,33 +369,33 @@ void
|
|||
RegionEditor::bounds_changed (const PropertyChange& what_changed)
|
||||
{
|
||||
if (what_changed.contains (ARDOUR::Properties::position) && what_changed.contains (ARDOUR::Properties::length)) {
|
||||
position_clock.set (_region->position(), true);
|
||||
end_clock.set (_region->position() + _region->length() - 1, true);
|
||||
length_clock.set (_region->length(), true);
|
||||
position_clock.set (_region->nt_position(), true);
|
||||
end_clock.set (_region->nt_last(), true);
|
||||
length_clock.set_duration (_region->nt_length(), true);
|
||||
} else if (what_changed.contains (ARDOUR::Properties::position)) {
|
||||
position_clock.set (_region->position(), true);
|
||||
end_clock.set (_region->position() + _region->length() - 1, true);
|
||||
position_clock.set (_region->nt_position(), true);
|
||||
end_clock.set (_region->nt_last(), true);
|
||||
} else if (what_changed.contains (ARDOUR::Properties::length)) {
|
||||
end_clock.set (_region->position() + _region->length() - 1, true);
|
||||
length_clock.set (_region->length(), true);
|
||||
end_clock.set (_region->nt_last(), true);
|
||||
length_clock.set_duration (_region->nt_length(), true);
|
||||
}
|
||||
|
||||
if (what_changed.contains (ARDOUR::Properties::sync_position) || what_changed.contains (ARDOUR::Properties::position)) {
|
||||
int dir;
|
||||
sampleoffset_t off = _region->sync_offset (dir);
|
||||
timecnt_t off = _region->sync_offset (dir);
|
||||
if (dir == -1) {
|
||||
off = -off;
|
||||
}
|
||||
|
||||
if (what_changed.contains (ARDOUR::Properties::sync_position)) {
|
||||
sync_offset_relative_clock.set (off, true);
|
||||
sync_offset_relative_clock.set_duration (off, true);
|
||||
}
|
||||
|
||||
sync_offset_absolute_clock.set (off + _region->position (), true);
|
||||
sync_offset_absolute_clock (_region->nt_position () + off, true);
|
||||
}
|
||||
|
||||
if (what_changed.contains (ARDOUR::Properties::start)) {
|
||||
start_clock.set (_region->start(), true);
|
||||
start_clock.set (_region->nt_start(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ SoundFileBox::SoundFileBox (bool /*persistent*/)
|
|||
table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
|
||||
table.attach (tempomap_value, 1, 2, 6, 7, FILL, FILL);
|
||||
|
||||
length_clock.set_is_duration (true, timepos_t());
|
||||
length_clock.set_mode (ARDOUR_UI::instance()->primary_clock->mode());
|
||||
timecode_clock.set_mode (AudioClock::Timecode);
|
||||
|
||||
|
@ -342,7 +343,7 @@ SoundFileBox::setup_labels (const string& filename)
|
|||
format_text.set_text ("MIDI");
|
||||
samplerate_value.set_text ("-");
|
||||
tags_entry.get_buffer()->set_text ("");
|
||||
timecode_clock.set (0);
|
||||
timecode_clock.set (timepos_t ());
|
||||
tags_entry.set_sensitive (false);
|
||||
|
||||
if (ms) {
|
||||
|
@ -355,7 +356,7 @@ SoundFileBox::setup_labels (const string& filename)
|
|||
channels_value.set_text (to_string(ms->num_tracks()));
|
||||
}
|
||||
}
|
||||
length_clock.set (ms->length(ms->natural_position()));
|
||||
length_clock.set_duration (timecnt_t (0));
|
||||
switch (ms->num_tempos()) {
|
||||
case 0:
|
||||
tempomap_value.set_text (_("No tempo data"));
|
||||
|
@ -376,7 +377,7 @@ SoundFileBox::setup_labels (const string& filename)
|
|||
}
|
||||
} else {
|
||||
channels_value.set_text ("");
|
||||
length_clock.set (0);
|
||||
length_clock.set (timepos_t());
|
||||
tempomap_value.set_text (_("No tempo data"));
|
||||
}
|
||||
|
||||
|
@ -397,8 +398,8 @@ SoundFileBox::setup_labels (const string& filename)
|
|||
samplerate_value.set_text ("");
|
||||
tags_entry.get_buffer()->set_text ("");
|
||||
|
||||
length_clock.set (0);
|
||||
timecode_clock.set (0);
|
||||
length_clock.set (timepos_t());
|
||||
timecode_clock.set (timepos_t());
|
||||
|
||||
tags_entry.set_sensitive (false);
|
||||
play_btn.set_sensitive (false);
|
||||
|
@ -429,8 +430,9 @@ SoundFileBox::setup_labels (const string& filename)
|
|||
samplecnt_t const nfr = _session ? _session->nominal_sample_rate() : 25;
|
||||
double src_coef = (double) nfr / sf_info.samplerate;
|
||||
|
||||
length_clock.set (sf_info.length * src_coef + 0.5, true);
|
||||
timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
|
||||
length_clock.set_is_duration (true, timepos_t());
|
||||
length_clock.set_duration (timecnt_t (samplecnt_t (llrint (sf_info.length * src_coef + 0.5))), true);
|
||||
timecode_clock.set (timepos_t (samplepos_t (llrint (sf_info.timecode * src_coef + 0.5))), true);
|
||||
|
||||
// this is a hack that is fixed in trunk, i think (august 26th, 2007)
|
||||
|
||||
|
@ -510,7 +512,7 @@ SoundFileBox::audition ()
|
|||
PropertyList plist;
|
||||
|
||||
plist.add (ARDOUR::Properties::start, 0);
|
||||
plist.add (ARDOUR::Properties::length, ms->length(ms->natural_position()));
|
||||
plist.add (ARDOUR::Properties::length, ms->length());
|
||||
plist.add (ARDOUR::Properties::name, rname);
|
||||
plist.add (ARDOUR::Properties::layer, 0);
|
||||
|
||||
|
@ -559,28 +561,29 @@ SoundFileBox::audition ()
|
|||
PropertyList plist;
|
||||
|
||||
plist.add (ARDOUR::Properties::start, 0);
|
||||
plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->natural_position()));
|
||||
plist.add (ARDOUR::Properties::length, srclist[0]->length());
|
||||
plist.add (ARDOUR::Properties::name, rname);
|
||||
plist.add (ARDOUR::Properties::layer, 0);
|
||||
|
||||
r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
|
||||
}
|
||||
|
||||
sampleoffset_t audition_position = 0;
|
||||
switch(_import_position) {
|
||||
timepos_t audition_position;
|
||||
|
||||
switch (_import_position) {
|
||||
case ImportAtTimestamp:
|
||||
audition_position = 0;
|
||||
break;
|
||||
case ImportAtPlayhead:
|
||||
audition_position = _session->transport_sample();
|
||||
audition_position = timepos_t (_session->transport_sample());
|
||||
break;
|
||||
case ImportAtStart:
|
||||
audition_position = _session->current_start_sample();
|
||||
audition_position = timepos_t (_session->current_start_sample());
|
||||
break;
|
||||
case ImportAtEditPoint:
|
||||
audition_position = PublicEditor::instance().get_preferred_edit_position ();
|
||||
break;
|
||||
}
|
||||
|
||||
r->set_position(audition_position);
|
||||
|
||||
_session->audition_region(r);
|
||||
|
@ -2074,7 +2077,7 @@ SoundFileOmega::do_something (int action)
|
|||
ImportMode mode = get_mode ();
|
||||
ImportDisposition chns = get_channel_disposition ();
|
||||
PluginInfoPtr instrument = instrument_combo.selected_instrument();
|
||||
samplepos_t where;
|
||||
timepos_t where;
|
||||
MidiTrackNameSource mts = get_midi_track_name_source ();
|
||||
MidiTempoMapDisposition mtd = (get_use_smf_tempo_map () ? SMFTempoUse : SMFTempoIgnore);
|
||||
bool with_midi_markers = get_use_smf_markers ();
|
||||
|
@ -2084,13 +2087,13 @@ SoundFileOmega::do_something (int action)
|
|||
where = PublicEditor::instance().get_preferred_edit_position ();
|
||||
break;
|
||||
case ImportAtTimestamp:
|
||||
where = -1;
|
||||
where = timepos_t::max (Temporal::AudioTime);
|
||||
break;
|
||||
case ImportAtPlayhead:
|
||||
where = _session->transport_sample();
|
||||
where = timepos_t (_session->transport_sample());
|
||||
break;
|
||||
case ImportAtStart:
|
||||
where = _session->current_start_sample();
|
||||
where = timepos_t (_session->current_start_sample());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,9 @@ StripSilenceDialog::StripSilenceDialog (Session* s, list<RegionView*> const & v)
|
|||
views.push_back (ViewInterval (*r));
|
||||
}
|
||||
|
||||
_minimum_length->set_is_duration (true, views.front().view->region()->nt_position());
|
||||
_fade_length->set_is_duration (true, views.front().view->region()->nt_position());
|
||||
|
||||
Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox);
|
||||
|
||||
Gtk::Table* table = Gtk::manage (new Gtk::Table (3, 3));
|
||||
|
@ -95,7 +98,7 @@ StripSilenceDialog::StripSilenceDialog (Session* s, list<RegionView*> const & v)
|
|||
|
||||
_minimum_length->set_session (s);
|
||||
_minimum_length->set_mode (AudioClock::Samples);
|
||||
_minimum_length->set (_minimum_length_value, true);
|
||||
_minimum_length->set_duration (timecnt_t (_minimum_length_value), true);
|
||||
|
||||
table->attach (*Gtk::manage (new Gtk::Label (_("Fade length"), 1, 0.5)), 0, 1, n, n + 1, Gtk::FILL);
|
||||
table->attach (*_fade_length, 1, 2, n, n + 1, Gtk::FILL);
|
||||
|
@ -103,7 +106,8 @@ StripSilenceDialog::StripSilenceDialog (Session* s, list<RegionView*> const & v)
|
|||
|
||||
_fade_length->set_session (s);
|
||||
_fade_length->set_mode (AudioClock::Samples);
|
||||
_fade_length->set (_fade_length_value, true);
|
||||
_fade_length->set_is_duration (true);
|
||||
_fade_length->set_duration (timecnt_t (_fade_length_value), true);
|
||||
|
||||
hbox->pack_start (*table);
|
||||
|
||||
|
@ -341,13 +345,13 @@ StripSilenceDialog::threshold_changed ()
|
|||
samplecnt_t
|
||||
StripSilenceDialog::minimum_length () const
|
||||
{
|
||||
return std::max((samplecnt_t)1, _minimum_length->current_duration (views.front().view->region()->position()));
|
||||
return std::max((samplecnt_t)1, _minimum_length->current_duration (views.front().view->region()->nt_position()).samples());
|
||||
}
|
||||
|
||||
samplecnt_t
|
||||
StripSilenceDialog::fade_length () const
|
||||
{
|
||||
return std::max((samplecnt_t)0, _fade_length->current_duration (views.front().view->region()->position()));
|
||||
return std::max((samplecnt_t)0, _fade_length->current_duration (views.front().view->region()->nt_position()).samples());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue