/* map using gain line */
- gain_line->view_to_model_y (y);
+ gain_line->view_to_model_coord (x, y);
trackview.session().begin_reversible_command (_("add gain control point"));
XMLNode &before = audio_region()->envelope()->get_state();
using namespace Editing;
using namespace Gnome; // for Canvas
-AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> al)
- : trackview (tv),
- _name (name),
- alist (al),
- _parent_group (parent)
+AutomationLine::AutomationLine (const string& name, TimeAxisView& tv, ArdourCanvas::Group& parent,
+ boost::shared_ptr<AutomationList> al,
+ const Evoral::TimeConverter<double, nframes_t>& converter)
+ : trackview (tv)
+ , _name (name)
+ , alist (al)
+ , _parent_group (parent)
+ , _time_converter (converter)
{
_interpolation = al->interpolation();
points_visible = false;
y = min (1.0, y);
y = _height - (y * _height);
- double const x = trackview.editor().frame_to_unit ((*cp.model())->when);
+ double const x = trackview.editor().frame_to_unit (_time_converter.to((*cp.model())->when));
trackview.editor().current_session()->begin_reversible_command (_("automation event move"));
trackview.editor().current_session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &get_state(), 0));
/* leave the x-coordinate alone */
- x = trackview.editor().frame_to_unit ((*cp.model())->when);
+ x = trackview.editor().frame_to_unit (_time_converter.to((*cp.model())->when));
}
void
AutomationLine::sync_model_with_view_line (uint32_t start, uint32_t end)
{
-
ControlPoint *p;
update_pending = true;
line to convert them to something relevant.
*/
- mr.xval = (nframes_t) floor (cp.get_x());
+ mr.xval = cp.get_x();
mr.yval = 1.0 - (cp.get_y() / _height);
/* if xval has not changed, set it directly from the model to avoid rounding errors */
- if (mr.xval == trackview.editor().frame_to_unit((*cp.model())->when)) {
- mr.xval = (nframes_t) (*cp.model())->when;
+ if (mr.xval == trackview.editor().frame_to_unit(_time_converter.to((*cp.model())->when))) {
+ mr.xval = (*cp.model())->when;
} else {
mr.xval = trackview.editor().unit_to_frame (mr.xval);
}
- /* virtual call: this will do the right thing
- for whatever particular type of line we are.
+ /* convert to model units
*/
- view_to_model_y (mr.yval);
+ view_to_model_coord (mr.xval, mr.yval);
/* part 2: find out where the model point is now
*/
- mr.xpos = (nframes_t) (*cp.model())->when;
+ mr.xpos = (*cp.model())->when;
mr.ypos = (*cp.model())->value;
/* part 3: get the position of the visual control
after = nth (cp.view_index() + 1);
if (before) {
- mr.xmin = (nframes_t) (*before->model())->when;
+ mr.xmin = (*before->model())->when;
mr.ymin = (*before->model())->value;
mr.start = before->model();
++mr.start;
* @param fraction y fraction
* @return string representation of this value, using dB if appropriate.
*/
-
string
AutomationLine::fraction_to_string (double fraction) const
{
snprintf (buf, sizeof (buf), "%.1f", coefficient_to_dB (slider_position_to_gain (fraction)));
}
} else {
- view_to_model_y (fraction);
+ double dummy = 0.0;
+ view_to_model_coord (dummy, fraction);
if (EventTypeMap::instance().is_integer (alist->parameter())) {
snprintf (buf, sizeof (buf), "%d", (int)fraction);
} else {
* @param s Value string in the form as returned by fraction_to_string.
* @return Corresponding y fraction.
*/
-
double
AutomationLine::string_to_fraction (string const & s) const
{
if (_uses_gain_mapping) {
v = gain_to_slider_position (dB_to_coefficient (v));
} else {
- model_to_view_y (v);
+ double dummy = 0.0;
+ model_to_view_coord (dummy, v);
}
return v;
for (uint32_t i = i1 ; i <= i2; i++) {
cp = nth (i);
- modify_view_point (*cp, trackview.editor().unit_to_frame (cp->get_x()), ((_height - cp->get_y()) /_height) + ydelta, with_push);
+ modify_view_point (*cp,
+ trackview.editor().unit_to_frame (_time_converter.to(cp->get_x())),
+ ((_height - cp->get_y()) /_height) + ydelta, with_push);
}
if (line_points.size() > 1) {
ControlPoint *acp = 0;
double unit_xval;
- /* xval is in frames */
-
unit_xval = trackview.editor().frame_to_unit (xval);
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
void
AutomationLine::get_selectables (nframes_t& start, nframes_t& end,
- double botfrac, double topfrac, list<Selectable*>& results)
+ double botfrac, double topfrac, list<Selectable*>& results)
{
double top;
double bot;
- nframes_t nstart;
- nframes_t nend;
+ double nstart;
+ double nend;
bool collecting = false;
/* Curse X11 and its inverted coordinate system! */
nend = 0;
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
-
- nframes_t when = (nframes_t) (*(*i)->model())->when;
+ double when = (*(*i)->model())->when;
if (when >= start && when <= end) {
for (ai = events.begin(); ai != events.end(); ++ai) {
+ double translated_x = (*ai)->when;
double translated_y = (*ai)->value;
- model_to_view_y (translated_y);
+ model_to_view_coord (translated_x, translated_y);
add_model_point (tmp_points, (*ai)->when, translated_y);
}
void
AutomationLine::add_model_point (ALPoints& tmp_points, double frame, double yfract)
{
- tmp_points.push_back (ALPoint (trackview.editor().frame_to_unit (frame),
+ tmp_points.push_back (ALPoint (trackview.editor().frame_to_unit (_time_converter.to(frame)),
_height - (yfract * _height)));
}
/* parent must create command */
XMLNode &before = get_state();
alist->clear();
- trackview.editor().current_session()->add_command (new MementoCommand<AutomationLine>(*this, &before, &get_state()));
+ trackview.editor().current_session()->add_command (
+ new MementoCommand<AutomationLine>(*this, &before, &get_state()));
trackview.editor().current_session()->commit_reversible_command ();
trackview.editor().current_session()->set_dirty ();
}
}
void
-AutomationLine::view_to_model_y (double& y) const
+AutomationLine::view_to_model_coord (double& x, double& y) const
{
/* TODO: This should be more generic ... */
if (alist->parameter().type() == GainAutomation ||
} else {
y = (int)(y * alist->parameter().max());
}
+
+ x = _time_converter.from(x);
}
void
-AutomationLine::model_to_view_y (double& y) const
+AutomationLine::model_to_view_coord (double& x, double& y) const
{
/* TODO: This should be more generic ... */
if (alist->parameter().type() == GainAutomation ||
} else {
y = y / (double)alist->parameter().max(); /* ... like this */
}
+
+ x = _time_converter.to(x);
}
#include "canvas.h"
#include "simplerect.h"
+#include <evoral/TimeConverter.hpp>
+
#include <pbd/undo.h>
#include <pbd/statefuldestructible.h>
#include <ardour/automation_list.h>
-
class AutomationLine;
class ControlPoint;
class PointSelection;
class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoingAway
{
public:
- AutomationLine (const string & name, TimeAxisView&, ArdourCanvas::Group&, boost::shared_ptr<ARDOUR::AutomationList>);
+ AutomationLine (const string& name, TimeAxisView&, ArdourCanvas::Group&,
+ boost::shared_ptr<ARDOUR::AutomationList>,
+ const Evoral::TimeConverter<double, nframes_t>& converter);
virtual ~AutomationLine ();
void queue_reset ();
bool control_points_adjacent (double xval, uint32_t& before, uint32_t& after);
/* dragging API */
-
virtual void start_drag (ControlPoint*, nframes_t x, float fraction);
virtual void point_drag(ControlPoint&, nframes_t x, float, bool with_push);
virtual void end_drag (ControlPoint*);
ControlPoint* nth (uint32_t);
uint32_t npoints() const { return control_points.size(); }
- string name() const { return _name; }
+ string name() const { return _name; }
bool visible() const { return _visible; }
- guint32 height() const { return _height; }
+ guint32 height() const { return _height; }
void set_line_color (uint32_t);
uint32_t get_line_color() const { return _line_color; }
string get_verbose_cursor_string (double) const;
string fraction_to_string (double) const;
double string_to_fraction (string const &) const;
- void view_to_model_y (double&) const;
- void model_to_view_y (double&) const;
+ void view_to_model_coord (double& x, double& y) const;
+ void model_to_view_coord (double& x, double& y) const;
void set_list(boost::shared_ptr<ARDOUR::AutomationList> list);
boost::shared_ptr<ARDOUR::AutomationList> the_list() const { return alist; }
uint32_t line_drag_cp2;
int64_t drag_x;
int64_t drag_distance;
-
- ARDOUR::AutomationList::InterpolationStyle _interpolation;
+
+ const Evoral::TimeConverter<double, nframes_t>& _time_converter;
+ ARDOUR::AutomationList::InterpolationStyle _interpolation;
void modify_view_point (ControlPoint&, double, double, bool with_push);
void reset_line_coords (ControlPoint&);
struct ModelRepresentation {
ARDOUR::AutomationList::iterator start;
ARDOUR::AutomationList::iterator end;
- nframes_t xpos;
+ double xpos;
double ypos;
- nframes_t xmin;
+ double xmin;
double ymin;
- nframes_t xmax;
+ double xmax;
double ymax;
- nframes_t xval;
+ double xval;
double yval;
};
#include <ardour/automation_control.h>
#include <ardour/event_type_map.h>
#include <ardour/session.h>
+#include <ardour/source.h>
#include "automation_region_view.h"
#include "public_editor.h"
{
_line = boost::shared_ptr<AutomationLine>(new AutomationLine(
ARDOUR::EventTypeMap::instance().to_symbol(list->parameter()),
- trackview, *get_canvas_group(), list));
+ trackview, *get_canvas_group(), list,
+ _region->source(0)->time_converter()));
_line->set_colors();
_line->set_interpolation(list->interpolation());
_line->show();
/* map using line */
- _line->view_to_model_y (y);
+ _line->view_to_model_coord (x, y);
view->session().begin_reversible_command (_("add automation event"));
XMLNode& before = _line->the_list()->get_state();
/* no regions, just a single line for the entire track (e.g. bus gain) */
} else {
+ static const Evoral::IdentityConverter<double,nframes_t> null_converter;
boost::shared_ptr<AutomationLine> line(new AutomationLine (
ARDOUR::EventTypeMap::instance().to_symbol(_control->parameter()),
*this,
*_canvas_display,
- _control->alist()));
+ _control->alist(),
+ null_converter));
line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
line->queue_reset ();
/* map using line */
- _line->view_to_model_y (y);
+ _line->view_to_model_coord (x, y);
_session.begin_reversible_command (_("add automation event"));
XMLNode& before = _control->alist()->get_state();
if (what_we_got) {
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
- double foo = (*x)->value;
- line.model_to_view_y (foo);
- (*x)->value = foo;
+ double when = (*x)->when;
+ double val = (*x)->value;
+ line.model_to_view_coord (when, val);
+ (*x)->when = when;
+ (*x)->value = val;
}
}
if (what_we_got) {
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
- double foo = (*x)->value;
- line.model_to_view_y (foo);
- (*x)->value = foo;
+ double when = (*x)->when;
+ double val = (*x)->value;
+ line.model_to_view_coord (when, val);
+ (*x)->when = when;
+ (*x)->value = val;
}
}
AutomationList copy (**p);
for (AutomationList::iterator x = copy.begin(); x != copy.end(); ++x) {
- double foo = (*x)->value;
- line.view_to_model_y (foo);
- (*x)->value = foo;
+ double when = (*x)->when;
+ double val = (*x)->value;
+ line.view_to_model_coord (when, val);
+ (*x)->when = when;
+ (*x)->value = val;
}
XMLNode &before = alist->get_state();
nframes64_t
MidiRegionView::beats_to_frames(double beats) const
{
- return midi_region()->midi_source()->converter().to(beats);
+ return midi_region()->midi_source()->time_converter().to(beats);
}
double
MidiRegionView::frames_to_beats(nframes64_t frames) const
{
- return midi_region()->midi_source()->converter().from(frames);
+ return midi_region()->midi_source()->time_converter().from(frames);
}
void
using namespace PBD;
AudioRegionGainLine::AudioRegionGainLine (const string & name, Session& s, AudioRegionView& r, ArdourCanvas::Group& parent, boost::shared_ptr<AutomationList> l)
- : AutomationLine (name, r.get_time_axis_view(), parent, l),
+ : AutomationLine (name, r.get_time_axis_view(), parent, l,
+ Evoral::IdentityConverter<double, nframes_t>()),
session (s),
rv (r)
{
void set_model(boost::shared_ptr<MidiModel> m) { _model = m; }
void drop_model() { _model.reset(); }
- BeatsFramesConverter& converter() { return _converter; }
+ const Evoral::TimeConverter<double, nframes_t>& time_converter() const {
+ return _converter;
+ }
protected:
virtual void flush_midi() = 0;
#include <set>
#include <sigc++/signal.h>
-
#include <pbd/statefuldestructible.h>
+#include <evoral/TimeConverter.hpp>
#include <ardour/ardour.h>
#include <ardour/session_object.h>
int load_transients (const std::string&);
void update_length (nframes_t pos, nframes_t cnt);
+
+ virtual const Evoral::TimeConverter<double, nframes_t>& time_converter() const {
+ return Evoral::IdentityConverter<double, nframes_t>();
+ }
protected:
DataType _type;
}
const double length_beats = ceil(t / (double)source->ppqn());
- smfs->update_length(0, smfs->converter().to(length_beats));
+ smfs->update_length(0, smfs->time_converter().to(length_beats));
smfs->end_write();
if (status.cancel) {
}
if (_model && !force_reload) {
+ cerr << _name << " not reloading model " << _model.get() << endl;
return;
}