another day or two's work on timeline type conversion

This commit is contained in:
Paul Davis 2020-10-04 22:52:17 -06:00
parent 04e8dbb342
commit 9d69fa3820
27 changed files with 378 additions and 351 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,7 +42,6 @@ class PatchChangeDialog : public ArdourDialog
{
public:
PatchChangeDialog (
const ARDOUR::BeatsSamplesConverter*,
ARDOUR::Session*,
Evoral::PatchChange<Temporal::Beats> const&,
ARDOUR::InstrumentInfo&,

View File

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

View File

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

View File

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

View File

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