intermediate, unfinished snapshot of ongoing timeline types work on GTK GUI

This commit is contained in:
Paul Davis 2020-09-26 09:14:59 -06:00
parent 69ab030f55
commit 7433bc27e0
59 changed files with 694 additions and 618 deletions

View file

@ -259,7 +259,7 @@ AnalysisWindow::analyze_data (Gtk::Button * /*button*/)
// std::cerr << "Analyzing ranges on track " << rui->route()->name() << std::endl;
FFTResult *res = fft_graph.prepareResult(rui->route_color(), rui->route()->name());
for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
for (std::list<TimelineRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
int n;
for (int channel = 0; channel < n_inputs; channel++) {

View file

@ -1904,13 +1904,13 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
}
if (_session->get_play_loop() && Config->get_loop_is_mode()) {
_session->request_locate (_session->locations()->auto_loop_location()->start(), MustRoll);
_session->request_locate (_session->locations()->auto_loop_location()->start().samples(), MustRoll);
} else {
if (UIConfiguration::instance().get_follow_edits()) {
list<AudioRange>& range = editor->get_selection().time;
if (range.front().start == _session->transport_sample()) { // if playhead is exactly at the start of a range, we assume it was placed there by follow_edits
list<TimelineRange>& range = editor->get_selection().time;
if (range.front().start().samples() == _session->transport_sample()) { // if playhead is exactly at the start of a range, we assume it was placed there by follow_edits
_session->request_play_range (&range, true);
_session->set_requested_return_sample (range.front().start); //force an auto-return here
_session->set_requested_return_sample (range.front().start().samples()); //force an auto-return here
}
}
_session->request_roll ();

View file

@ -188,7 +188,7 @@ ARDOUR_UI::update_transport_clocks (samplepos_t pos)
case DeltaOriginMarker:
{
Location* loc = _session->locations()->clock_origin_location ();
primary_clock->set (pos, false, loc ? loc->start() : 0);
primary_clock->set (pos, false, loc ? loc->start_sample() : 0);
}
break;
}
@ -203,7 +203,7 @@ ARDOUR_UI::update_transport_clocks (samplepos_t pos)
case DeltaOriginMarker:
{
Location* loc = _session->locations()->clock_origin_location ();
secondary_clock->set (pos, false, loc ? loc->start() : 0);
secondary_clock->set (pos, false, loc ? loc->start_sample() : 0);
}
break;
}

View file

@ -114,7 +114,7 @@ void
ARDOUR_UI::create_xrun_marker (samplepos_t where)
{
if (_session) {
Location *location = new Location (*_session, where, where, _("xrun"), Location::IsMark, 0);
Location *location = new Location (*_session, timepos_t (where), timepos_t (where), _("xrun"), Location::IsMark);
_session->locations()->add (location);
}
}

View file

@ -891,6 +891,85 @@ AudioClock::set (samplepos_t when, bool force, samplecnt_t offset)
}
}
finish_set (timepos_t (when), btn_en);
}
void
AudioClock::set_duration (Temporal::timecnt_t const & d, bool force, Temporal::timecnt_t const & offset)
{
set_time (timepos_t (d), force, offset);
}
void
AudioClock::set_time (Temporal::timepos_t const & w, bool force, Temporal::timecnt_t const & offset)
{
Temporal::timepos_t when (w);
if ((!force && !is_visible()) || _session == 0) {
return;
}
if (is_duration) {
when = when.earlier (offset);
}
if (when > _limit_pos) {
when = _limit_pos;
} else if (when < -_limit_pos) {
when = -_limit_pos;
}
if (when == last_when && !force) {
#if 0 // XXX return if no change and no change forced. verify Aug/2014
if (_mode != Timecode && _mode != MinSec) {
/* may need to force display of TC source
* time, so don't return early.
*/
/* ^^ Why was that?, delta times?
* Timecode FPS, pull-up/down, etc changes
* trigger a 'session_property_changed' which
* eventually calls set(last_when, true)
*
* re-rendering the clock every 40ms or so just
* because we can is not ideal.
*/
return;
}
#else
return;
#endif
}
bool btn_en = false;
if (!editing) {
switch (_mode) {
case Timecode:
set_timecode (when.sample(), force);
break;
case BBT:
_set_bbt (when.bbt(), when.bbt() < Temporal::timepos_t (Temporal::BBT_Time()));
btn_en = true;
break;
case MinSec:
set_minsec (when.sample(), force);
break;
case Samples:
set_samples (when.sample(), force);
break;
}
}
finish_set (when, btn_en);
}
void
AudioClock::finish_set (Temporal::timepos_t const & when, bool btn_en)
{
if (_with_info) {
_left_btn.set_sensitive (btn_en);
_right_btn.set_sensitive (btn_en);
@ -2295,14 +2374,25 @@ AudioClock::set_editable (bool yn)
}
void
AudioClock::set_is_duration (bool yn)
AudioClock::set_is_duration (bool yn, timepos_t const & p)
{
if (yn == is_duration) {
if (yn) {
/* just reset position */
duration_position = p;
}
return;
}
is_duration = yn;
AudioClock::set (last_when, true);
if (yn) {
duration_position = p;
} else {
duration_position = timepos_t ();
}
set_time (last_when, true);
}
void

View file

@ -74,11 +74,15 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr
void focus ();
virtual void set (samplepos_t, bool force = false, ARDOUR::samplecnt_t offset = 0);
void set_time (Temporal::timepos_t const &, bool force = false, Temporal::timecnt_t const & offset = Temporal::timecnt_t());
void set_duration (Temporal::timecnt_t const &, bool force = false, Temporal::timecnt_t const & offset = Temporal::timecnt_t());
void set_from_playhead ();
void locate ();
void set_mode (Mode, bool noemit = false);
void set_bbt_reference (samplepos_t);
void set_is_duration (bool);
void set_is_duration (bool, Temporal::timepos_t const &);
void copy_text_to_clipboard () const;
@ -139,6 +143,7 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr
bool edit_is_negative;
samplepos_t _limit_pos;
Temporal::timepos_t duration_position;
ARDOUR::samplecnt_t _offset;
@ -223,6 +228,7 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr
void set_seconds (samplepos_t, bool);
void set_samples (samplepos_t, bool);
void set_out_of_bounds (bool negative);
void finish_set (Temporal::timepos_t const &, bool);
void set_clock_dimensions (Gtk::Requisition&);

View file

@ -126,7 +126,7 @@ AudioStreamView::create_region_view (boost::shared_ptr<Region> r, bool wait_for_
insensitive to events
*/
if (region->length() == 1) {
if (region->length_samples() == 1) {
region_view->set_sensitive (false);
}
@ -226,7 +226,7 @@ AudioStreamView::setup_rec_box ()
samplepos_t start = 0;
if (rec_regions.size() > 0) {
start = rec_regions.back().first->start()
start = rec_regions.back().first->start_sample()
+ _trackview.track()->get_captured_samples(rec_regions.size()-1);
}
@ -241,7 +241,7 @@ AudioStreamView::setup_rec_box ()
boost::dynamic_pointer_cast<AudioRegion>(RegionFactory::create (sources, plist, false)));
assert(region);
region->set_position (_trackview.session()->transport_sample());
region->set_position (timepos_t (_trackview.session()->transport_sample()));
rec_regions.push_back (make_pair(region, (RegionView*) 0));
}
@ -355,20 +355,20 @@ AudioStreamView::update_rec_regions (samplepos_t start, samplecnt_t cnt)
continue;
}
samplecnt_t origlen = region->length();
samplecnt_t origlen = region->length_samples();
if (region == rec_regions.back().first && rec_active) {
if (last_rec_data_sample > region->start()) {
if (last_rec_data_sample > region->start_sample()) {
samplecnt_t nlen = last_rec_data_sample - region->start();
samplecnt_t nlen = last_rec_data_sample - region->start_sample();
if (nlen != region->length()) {
if (nlen != region->length_samples()) {
region->suspend_property_changes ();
/* set non-musical position / length */
region->set_position (_trackview.track()->get_capture_start_sample(n));
region->set_length (nlen, 0);
region->set_position (timepos_t (_trackview.track()->get_capture_start_sample(n)));
region->set_length (timecnt_t (nlen));
region->resume_property_changes ();
if (origlen == 1) {
@ -377,11 +377,11 @@ AudioStreamView::update_rec_regions (samplepos_t start, samplecnt_t cnt)
setup_new_rec_layer_time (region);
}
check_record_layers (region, (region->position() - region->start() + start + cnt));
check_record_layers (region, (region->position_sample() - region->start_sample() + start + cnt));
/* also update rect */
ArdourCanvas::Rectangle * rect = rec_rects[n].rectangle;
gdouble xend = _trackview.editor().sample_to_pixel (region->position() + region->length());
gdouble xend = _trackview.editor().sample_to_pixel (region->position_sample() + region->length_samples());
rect->set_x1 (xend);
}
@ -389,13 +389,13 @@ AudioStreamView::update_rec_regions (samplepos_t start, samplecnt_t cnt)
samplecnt_t nlen = _trackview.track()->get_captured_samples(n);
if (nlen != region->length()) {
if (nlen != region->length_samples()) {
if (region->source_length(0) >= region->start() + nlen) {
if (region->source_length(0) >= region->start_sample() + nlen) {
region->suspend_property_changes ();
region->set_position (_trackview.track()->get_capture_start_sample(n));
region->set_length (nlen, 0);
region->set_position (timepos_t (_trackview.track()->get_capture_start_sample(n)));
region->set_length (timecnt_t (nlen));
region->resume_property_changes ();
if (origlen == 1) {
@ -451,8 +451,8 @@ AudioStreamView::hide_xfades_with (boost::shared_ptr<AudioRegion> ar)
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
switch (arv->region()->coverage (ar->position(), ar->last_sample())) {
case Evoral::OverlapNone:
switch (arv->region()->coverage (ar->nt_position(), ar->nt_last())) {
case Temporal::OverlapNone:
break;
default:
if (arv->start_xfade_visible ()) {

View file

@ -83,15 +83,14 @@ AutomationLine::AutomationLine (const string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
boost::shared_ptr<AutomationList> al,
const ParameterDescriptor& desc,
Evoral::TimeConverter<double, samplepos_t>* converter)
const ParameterDescriptor& desc)
: trackview (tv)
, _name (name)
, alist (al)
, _time_converter (converter ? converter : new Evoral::IdentityConverter<double, samplepos_t>)
, _parent_group (parent)
, _offset (0)
, _maximum_time (max_samplepos)
, _maximum_time (timepos_t::max (al->time_domain()))
, _fill (false)
, _desc (desc)
{
@ -1178,11 +1177,29 @@ AutomationLine::set_state (const XMLNode &node, int version)
return alist->set_state (node, version);
}
void
AutomationLine::view_to_model_coord (double& x, double& y) const
Temporal::timepos_t
AutomationLine::view_to_model_coord (double x, double& y) const
{
x = _time_converter->from (x);
assert (alist->time_style() != Temporal::BarTime);
view_to_model_coord_y (y);
Temporal::timepos_t w;
switch (alist->time_style()) {
case Temporal::AudioTime:
return timepos_t (samplepos_t (x));
break;
case Temporal::BeatTime:
return timepos_t (Beats::from_double (x));
break;
default:
/*NOTREACHED*/
break;
}
/*NOTREACHED*/
return timepos_t();
}
void
@ -1251,11 +1268,12 @@ AutomationLine::model_to_view_coord_y (double& y) const
y = _desc.to_interface (y);
}
void
AutomationLine::model_to_view_coord (double& x, double& y) const
double
AutomationLine::model_to_view_coord (Evoral::ControlEvent const & ev, double& y) const
{
Temporal::timepos_t w (ev.when());
model_to_view_coord_y (y);
x = _time_converter->to (x) - _offset;
return (w).earlier (_offset).samples();
}
/** Called when our list has announced that its interpolation style has changed */
@ -1336,7 +1354,7 @@ AutomationLine::memento_command_binder ()
* to the start of the track or region that it is on.
*/
void
AutomationLine::set_maximum_time (samplecnt_t t)
AutomationLine::set_maximum_time (Temporal::timepos_t const & t)
{
if (_maximum_time == t) {
return;

View file

@ -33,8 +33,6 @@
#include <sigc++/signal.h>
#include "evoral/TimeConverter.h"
#include "pbd/undo.h"
#include "pbd/statefuldestructible.h"
#include "pbd/memento_command.h"
@ -71,8 +69,7 @@ public:
TimeAxisView& tv,
ArdourCanvas::Item& parent,
boost::shared_ptr<ARDOUR::AutomationList> al,
const ARDOUR::ParameterDescriptor& desc,
Evoral::TimeConverter<double, ARDOUR::samplepos_t>* converter = 0);
const ARDOUR::ParameterDescriptor& desc);
virtual ~AutomationLine ();
@ -126,9 +123,9 @@ public:
std::string fraction_to_string (double) const;
std::string delta_to_string (double) const;
double string_to_fraction (std::string const &) const;
void 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;
void model_to_view_coord (double& x, double& y) const;
Temporal::timepos_t model_to_view_coord (Evoral::ControlEvent const &, double& y) const;
void model_to_view_coord_y (double &) const;
double compute_delta (double from, double to) const;
@ -151,20 +148,16 @@ public:
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
const Evoral::TimeConverter<double, ARDOUR::samplepos_t>& time_converter () const {
return *_time_converter;
}
std::pair<ARDOUR::samplepos_t, ARDOUR::samplepos_t> get_point_x_range () const;
void set_maximum_time (ARDOUR::samplecnt_t);
ARDOUR::samplecnt_t maximum_time () const {
void set_maximum_time (Temporal::timepos_t const &);
Temporal::timepos_t maximum_time () const {
return _maximum_time;
}
void set_offset (ARDOUR::samplecnt_t);
ARDOUR::samplecnt_t offset () { return _offset; }
void set_width (ARDOUR::samplecnt_t);
void set_offset (Temporal::timecnt_t const &);
Temporal::timecnt_t offset () { return _offset; }
void set_width (Temporal::timecnt_t const &);
samplepos_t session_position (ARDOUR::AutomationList::const_iterator) const;
@ -175,9 +168,6 @@ protected:
uint32_t _line_color;
boost::shared_ptr<ARDOUR::AutomationList> alist;
Evoral::TimeConverter<double, ARDOUR::samplepos_t>* _time_converter;
/** true if _time_converter belongs to us (ie we should delete it on destruction) */
bool _our_time_converter;
VisibleAspects _visible;
@ -231,7 +221,7 @@ private:
/** offset from the start of the automation list to the start of the line, so that
* a +ve offset means that the 0 on the line is at _offset in the list
*/
ARDOUR::samplecnt_t _offset;
Temporal::timecnt_t _offset;
bool is_stepped() const;
void update_visibility ();
@ -244,7 +234,7 @@ private:
PBD::ScopedConnectionList _list_connections;
/** maximum time that a point on this line can be at, relative to the position of its region or start of its track */
ARDOUR::samplecnt_t _maximum_time;
Temporal::timepos_t _maximum_time;
bool _fill;

View file

@ -44,6 +44,8 @@
#include "pbd/i18n.h"
using namespace Temporal;
AutomationRegionView::AutomationRegionView (ArdourCanvas::Container* parent,
AutomationTimeAxisView& time_axis,
boost::shared_ptr<ARDOUR::Region> region,
@ -52,11 +54,9 @@ AutomationRegionView::AutomationRegionView (ArdourCanvas::Container*
double spu,
uint32_t basic_color)
: RegionView(parent, time_axis, region, spu, basic_color, true)
, _region_relative_time_converter(region->session().tempo_map(), region->position())
, _source_relative_time_converter(region->session().tempo_map(), region->position() - region->start())
, _parameter(param)
{
TimeAxisViewItem::set_position (_region->position(), this);
TimeAxisViewItem::set_position (_region->nt_position(), this);
if (list) {
assert(list->parameter() == param);
@ -83,7 +83,7 @@ AutomationRegionView::init (bool /*wfd*/)
RegionView::init (false);
reset_width_dependent_items ((double) _region->length() / samples_per_pixel);
reset_width_dependent_items ((double) _region->length_samples() / samples_per_pixel);
set_height (trackview.current_height());
@ -100,13 +100,12 @@ AutomationRegionView::create_line (boost::shared_ptr<ARDOUR::AutomationList> lis
ARDOUR::EventTypeMap::instance().to_symbol(list->parameter()),
trackview, *get_canvas_group(), list,
boost::dynamic_pointer_cast<ARDOUR::MidiRegion> (_region),
_parameter,
&_source_relative_time_converter));
_parameter));
_line->set_colors();
_line->set_height ((uint32_t)rint(trackview.current_height() - 2.5 - NAME_HIGHLIGHT_SIZE));
_line->set_visibility (AutomationLine::VisibleAspects (AutomationLine::Line|AutomationLine::ControlPoints));
_line->set_maximum_time (_region->length());
_line->set_offset (_region->start ());
_line->set_maximum_time (timepos_t (_region->nt_length()));
_line->set_offset (_region->nt_start ());
}
uint32_t
@ -157,7 +156,8 @@ AutomationRegionView::canvas_group_event (GdkEvent* ev)
/* guard points only if primary modifier is used */
bool with_guard_points = Gtkmm2ext::Keyboard::modifier_state_equals (ev->button.state, Gtkmm2ext::Keyboard::PrimaryModifier);
add_automation_event (ev, e.pixel_to_sample (x) - _region->position() + _region->start(), y, with_guard_points);
#warning NUTEMPO what if this automation list is not using audio time?
add_automation_event (ev, timepos_t (e.pixel_to_sample (x) - _region->position_sample() + _region->start_sample()), y, with_guard_points);
return true;
}
@ -168,10 +168,11 @@ AutomationRegionView::canvas_group_event (GdkEvent* ev)
* @param y y position, relative to our TimeAxisView.
*/
void
AutomationRegionView::add_automation_event (GdkEvent *, samplepos_t when, double y, bool with_guard_points)
AutomationRegionView::add_automation_event (GdkEvent *, timepos_t const & w, double y, bool with_guard_points)
{
boost::shared_ptr<Evoral::Control> c = _region->control(_parameter, true);
boost::shared_ptr<ARDOUR::AutomationControl> ac = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(c);
timepos_t when (w); /* the non-const copy */
if (!_line) {
assert(ac);
@ -184,11 +185,13 @@ AutomationRegionView::add_automation_event (GdkEvent *, samplepos_t when, double
/* compute vertical fractional position */
y = 1.0 - (y / _line->height());
/* snap sample, prepare conversion to double beats */
double when_d = snap_sample_to_sample (when - _region->start ()).sample + _region->start ();
/* snap time */
/* convert 'when' to music-time relative to the region and scale y from interface to internal */
_line->view_to_model_coord (when_d, y);
when = snap_region_time_to_region_time (when.earlier (_region->nt_start()), false) + _region->nt_start ();
/* map using line */
_line->view_to_model_coord_y (y);
if (UIConfiguration::instance().get_new_automation_points_on_lane()) {
if (c->list()->size () == 0) {
@ -205,6 +208,7 @@ AutomationRegionView::add_automation_event (GdkEvent *, samplepos_t when, double
XMLNode& before = _line->the_list()->get_state();
<<<<<<< HEAD
if (_line->the_list()->editor_add (when_d, y, with_guard_points)) {
if (ac->automation_state () == ARDOUR::Off) {
@ -214,6 +218,9 @@ AutomationRegionView::add_automation_event (GdkEvent *, samplepos_t when, double
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();
@ -226,7 +233,7 @@ AutomationRegionView::add_automation_event (GdkEvent *, samplepos_t when, double
}
bool
AutomationRegionView::paste (samplepos_t pos,
AutomationRegionView::paste (timepos_t const & pos,
unsigned paste_count,
float times,
boost::shared_ptr<const ARDOUR::AutomationList> slist)
@ -241,24 +248,18 @@ AutomationRegionView::paste (samplepos_t pos
return false;
}
AutomationType src_type = (AutomationType)slist->parameter().type ();
double len = slist->length();
timecnt_t len = slist->length();
timepos_t p (pos);
/* add multi-paste offset if applicable */
if (parameter_is_midi (src_type)) {
// convert length to samples (incl tempo-ramps)
len = BeatsSamplesConverter (view->session()->tempo_map(), pos).to (Temporal::Beats::from_double (len * paste_count));
pos += view->editor ().get_paste_offset (pos, paste_count > 0 ? 1 : 0, len);
} else {
pos += view->editor ().get_paste_offset (pos, paste_count, len);
}
p += view->editor ().get_paste_offset (pos, paste_count > 0 ? 1 : 0, len);
/* convert sample-position to model's unit and position */
const double model_pos = _source_relative_time_converter.from (
pos - _source_relative_time_converter.origin_b());
timepos_t model_pos = timepos_t (source_relative_distance (timecnt_t (p, timepos_t()), slist->time_domain()));
XMLNode& before = my_list->get_state();
my_list->paste(*slist, model_pos, BeatsSamplesConverter (view->session()->tempo_map(), pos));
#warning NUTEMPO fixme needs new tempo map
//my_list->paste (*slist, model_pos, _region->session().tempo_map());
view->session()->add_command(
new MementoCommand<ARDOUR::AutomationList>(_line->memento_command_binder(), &before, &my_list->get_state()));
@ -276,10 +277,10 @@ AutomationRegionView::set_height (double h)
}
bool
AutomationRegionView::set_position (samplepos_t pos, void* src, double* ignored)
AutomationRegionView::set_position (timepos_t const & pos, void* src, double* ignored)
{
if (_line) {
_line->set_maximum_time (_region->length ());
_line->set_maximum_time (timepos_t (_region->nt_length ()));
}
return RegionView::set_position(pos, src, ignored);
@ -302,25 +303,16 @@ AutomationRegionView::region_resized (const PBD::PropertyChange& what_changed)
{
RegionView::region_resized (what_changed);
if (what_changed.contains (ARDOUR::Properties::position)) {
_region_relative_time_converter.set_origin_b(_region->position());
}
if (what_changed.contains (ARDOUR::Properties::start) ||
what_changed.contains (ARDOUR::Properties::position)) {
_source_relative_time_converter.set_origin_b (_region->position() - _region->start());
}
if (!_line) {
return;
}
if (what_changed.contains (ARDOUR::Properties::start)) {
_line->set_offset (_region->start ());
_line->set_offset (_region->nt_start ());
}
if (what_changed.contains (ARDOUR::Properties::length)) {
_line->set_maximum_time (_region->length());
_line->set_maximum_time (timepos_t (_region->nt_length()));
}
}

View file

@ -50,19 +50,11 @@ public:
void init (bool wfd);
bool paste (samplepos_t pos,
bool paste (Temporal::timepos_t const & pos,
unsigned paste_count,
float times,
boost::shared_ptr<const ARDOUR::AutomationList> slist);
ARDOUR::DoubleBeatsSamplesConverter const & region_relative_time_converter () const {
return _region_relative_time_converter;
}
ARDOUR::DoubleBeatsSamplesConverter const & source_relative_time_converter () const {
return _source_relative_time_converter;
}
inline AutomationTimeAxisView* automation_view() const
{ return dynamic_cast<AutomationTimeAxisView*>(&trackview); }
@ -78,17 +70,15 @@ public:
protected:
void create_line(boost::shared_ptr<ARDOUR::AutomationList> list);
bool set_position(samplepos_t pos, void* src, double* ignored);
bool set_position(Temporal::timepos_t const & pos, void* src, double* ignored);
void region_resized (const PBD::PropertyChange&);
bool canvas_group_event(GdkEvent* ev);
void add_automation_event (GdkEvent* event, samplepos_t when, double y, bool with_guard_points);
void add_automation_event (GdkEvent* event, Temporal::timepos_t const & when, double y, bool with_guard_points);
void mouse_mode_changed ();
void entered();
void exited();
private:
ARDOUR::DoubleBeatsSamplesConverter _region_relative_time_converter;
ARDOUR::DoubleBeatsSamplesConverter _source_relative_time_converter;
Evoral::Parameter _parameter;
boost::shared_ptr<AutomationLine> _line;
PBD::ScopedConnection _mouse_mode_connection;

View file

@ -323,7 +323,7 @@ AutomationStreamView::get_lines () const
}
bool
AutomationStreamView::paste (samplepos_t pos,
AutomationStreamView::paste (timepos_t const & pos,
unsigned paste_count,
float times,
boost::shared_ptr<ARDOUR::AutomationList> alist)
@ -339,7 +339,7 @@ AutomationStreamView::paste (samplepos_t pos,
list<RegionView*>::const_iterator prev = region_views.begin ();
for (list<RegionView*>::const_iterator i = region_views.begin(); i != region_views.end(); ++i) {
if ((*i)->region()->position() > pos) {
if ((*i)->region()->nt_position() > pos) {
break;
}
prev = i;
@ -348,7 +348,7 @@ AutomationStreamView::paste (samplepos_t pos,
boost::shared_ptr<Region> r = (*prev)->region ();
/* If *prev doesn't cover pos, it's no good */
if (r->position() > pos || ((r->position() + r->length()) < pos)) {
if (r->nt_position() > pos || ((r->nt_position() + r->nt_length()) < pos)) {
return false;
}

View file

@ -68,7 +68,7 @@ public:
std::list<boost::shared_ptr<AutomationLine> > get_lines () const;
bool paste (samplepos_t pos,
bool paste (Temporal::timepos_t const & pos,
unsigned paste_count,
float times,
boost::shared_ptr<ARDOUR::AutomationList> list);

View file

@ -107,7 +107,7 @@ public:
/* editing operations */
void cut_copy_clear (Selection&, Editing::CutCopyOp);
bool paste (ARDOUR::samplepos_t, const Selection&, PasteContext&, const int32_t sub_num);
bool paste (Temporal::timepos_t const &, const Selection&, PasteContext&);
int set_state (const XMLNode&, int version);

View file

@ -1749,7 +1749,7 @@ Editor::loudness_analyze_range_selection ()
if (!pl || !rui) {
continue;
}
for (std::list<AudioRange>::iterator j = ts.begin (); j != ts.end (); ++j) {
for (std::list<TimelineRange>::iterator j = ts.begin (); j != ts.end (); ++j) {
total_work += j->length ();
}
}
@ -2610,7 +2610,7 @@ Editor::set_snapped_cursor_position (samplepos_t pos)
* @param event Event to get current key modifier information from, or 0.
*/
void
Editor::snap_to_with_modifier (MusicSample& start, GdkEvent const * event, RoundMode direction, SnapPref pref)
Editor::snap_to_with_modifier (Temporal::timepos_t & start, GdkEvent const * event, Temporal::RoundMode direction, bool for_mark)
{
if (!_session || !event) {
return;
@ -2618,33 +2618,32 @@ Editor::snap_to_with_modifier (MusicSample& start, GdkEvent const * event, Round
if (ArdourKeyboard::indicates_snap (event->button.state)) {
if (_snap_mode == SnapOff) {
snap_to_internal (start, direction, pref);
snap_to_internal (start, direction, for_mark);
} else {
start.set (start.sample, 0);
start = start.sample();
}
} else {
if (_snap_mode != SnapOff) {
snap_to_internal (start, direction, pref);
snap_to_internal (start, direction, for_mark);
} else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) {
/* SnapOff, but we pressed the snap_delta modifier */
snap_to_internal (start, direction, pref);
snap_to_internal (start, direction, for_mark);
} else {
start.set (start.sample, 0);
start = start.sample ();
}
}
}
void
Editor::snap_to (MusicSample& start, RoundMode direction, SnapPref pref, bool ensure_snap)
Editor::snap_to (Temporal::timepos_t & start, Temporal::RoundMode direction, bool for_mark, bool ensure_snap)
{
if (!_session || (_snap_mode == SnapOff && !ensure_snap)) {
start.set (start.sample, 0);
start = start.sample ();
return;
}
snap_to_internal (start, direction, pref, ensure_snap);
snap_to_internal (start, direction, for_mark, ensure_snap);
}
static void
check_best_snap (samplepos_t presnap, samplepos_t &test, samplepos_t &dist, samplepos_t &best)
{
@ -2936,7 +2935,7 @@ Editor::snap_to_marker (samplepos_t presnap, RoundMode direction)
}
void
Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref, bool ensure_snap)
Editor::snap_to_internal (timepos_t const & start, RoundMode direction, SnapPref pref, bool ensure_snap)
{
UIConfiguration const& uic (UIConfiguration::instance ());
const samplepos_t presnap = start.sample;
@ -4054,23 +4053,28 @@ Editor::set_show_touched_automation (bool yn)
instant_save ();
}
samplecnt_t
Editor::get_paste_offset (samplepos_t pos, unsigned paste_count, samplecnt_t duration)
PlaylistSelector&
Editor::playlist_selector () const
{
return *_playlist_selector;
}
Temporal::timecnt_t
Editor::get_paste_offset (Temporal::timepos_t const & pos, unsigned paste_count, Temporal::timecnt_t const & duration)
{
if (paste_count == 0) {
/* don't bother calculating an offset that will be zero anyway */
return 0;
return timecnt_t (0, timepos_t());
}
/* calculate basic unsnapped multi-paste offset */
samplecnt_t offset = paste_count * duration;
Temporal::timecnt_t offset = duration * paste_count;
/* snap offset so pos + offset is aligned to the grid */
MusicSample offset_pos (pos + offset, 0);
snap_to(offset_pos, RoundUpMaybe);
offset = offset_pos.sample - pos;
Temporal::timepos_t snap_pos (pos + offset);
snap_to (snap_pos, Temporal::RoundUpMaybe);
return offset;
return pos.distance (snap_pos);
}
unsigned

View file

@ -351,10 +351,10 @@ public:
/* nudge is initiated by transport controls owned by ARDOUR_UI */
samplecnt_t get_nudge_distance (samplepos_t pos, samplecnt_t& next);
samplecnt_t get_paste_offset (samplepos_t pos, unsigned paste_count, samplecnt_t duration);
unsigned get_grid_beat_divisions(samplepos_t position);
Temporal::Beats get_grid_type_as_beats (bool& success, samplepos_t position);
Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next);
Temporal::timecnt_t get_paste_offset (Temporal::timepos_t const & pos, unsigned paste_count, Temporal::timecnt_t const & duration);
unsigned get_grid_beat_divisions(Temporal::timepos_t const & position);
Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position);
int32_t get_grid_music_divisions (uint32_t event_state);
@ -384,7 +384,7 @@ public:
void set_group_tabs ();
/* returns the left-most and right-most time that the gui should allow the user to scroll to */
std::pair <samplepos_t,samplepos_t> session_gui_extents (bool use_extra = true) const;
std::pair <Temporal::timepos_t,Temporal::timepos_t> session_gui_extents (bool use_extra = true) const;
/* RTAV Automation display option */
bool show_touched_automation () const;
@ -457,15 +457,13 @@ public:
ARDOUR::SrcQuality quality,
ARDOUR::MidiTrackNameSource mts,
ARDOUR::MidiTempoMapDisposition mtd,
samplepos_t& pos,
boost::shared_ptr<ARDOUR::PluginInfo> instrument = boost::shared_ptr<ARDOUR::PluginInfo>(),
bool with_markers = false
);
Temporal::timepos_t& pos,
boost::shared_ptr<ARDOUR::PluginInfo> instrument = boost::shared_ptr<ARDOUR::PluginInfo>());
void do_embed (std::vector<std::string> paths,
Editing::ImportDisposition disposition,
Editing::ImportMode mode,
samplepos_t& pos,
Temporal::timepos_t& pos,
boost::shared_ptr<ARDOUR::PluginInfo> instrument = boost::shared_ptr<ARDOUR::PluginInfo>());
void get_regionview_corresponding_to (boost::shared_ptr<ARDOUR::Region> region, std::vector<RegionView*>& regions);
@ -477,15 +475,15 @@ public:
TrackViewList axis_views_from_routes (boost::shared_ptr<ARDOUR::RouteList>) const;
void snap_to (ARDOUR::MusicSample& first,
void snap_to (Temporal::timepos_t & first,
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
ARDOUR::SnapPref pref = ARDOUR::SnapToAny_Visual,
bool ensure_snap = false);
void snap_to_with_modifier (ARDOUR::MusicSample& first,
void snap_to_with_modifier (Temporal::timepos_t & first,
GdkEvent const* ev,
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
ARDOUR::SnapPref pref = ARDOUR::SnapToAny_Visual);
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual);
void set_snapped_cursor_position (samplepos_t pos);
@ -729,7 +727,7 @@ private:
void setup_lines ();
void set_name (const std::string&);
void set_position (samplepos_t start, samplepos_t end = 0);
void set_position (Temporal::timepos_t const & start, Temporal::timepos_t const & end = Temporal::timepos_t());
void set_color_rgba (uint32_t);
};
@ -1393,8 +1391,8 @@ private:
void bring_in_external_audio (Editing::ImportMode mode, samplepos_t& pos);
bool idle_drop_paths (std::vector<std::string> paths, samplepos_t sample, double ypos, bool copy);
void drop_paths_part_two (const std::vector<std::string>& paths, samplepos_t sample, double ypos, bool copy);
bool idle_drop_paths (std::vector<std::string> paths, Temporal::timepos_t sample, double ypos, bool copy);
void drop_paths_part_two (const std::vector<std::string>& paths, Temporal::timepos_t const & sample, double ypos, bool copy);
int import_sndfiles (std::vector<std::string> paths,
Editing::ImportDisposition disposition,
@ -1977,7 +1975,7 @@ private:
/* object rubberband select process */
void select_all_within (samplepos_t, samplepos_t, double, double, TrackViewList const &, Selection::Operation, bool);
void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, TrackViewList const &, Selection::Operation, bool);
ArdourCanvas::Rectangle* rubberband_rect;
@ -2081,7 +2079,7 @@ private:
void external_edit_region ();
int write_audio_selection (TimeSelection&);
bool write_audio_range (ARDOUR::AudioPlaylist&, const ARDOUR::ChanCount& channels, std::list<ARDOUR::AudioRange>&);
bool write_audio_range (ARDOUR::AudioPlaylist&, const ARDOUR::ChanCount& channels, std::list<ARDOUR::TimelineRange>&);
void write_selection ();
@ -2269,10 +2267,14 @@ private:
ARDOUR::RoundMode direction,
ARDOUR::SnapPref gpref);
void snap_to_internal (ARDOUR::MusicSample& first,
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
bool ensure_snap = false);
void snap_to_internal (Temporal::timepos_t & first,
Temporal::RoundMode direction = Temporal::RoundNearest,
bool for_mark = false,
bool ensure_snap = false);
void timecode_snap_to_internal (Temporal::timepos_t & first,
Temporal::RoundMode direction = Temporal::RoundNearest,
bool for_mark = false);
samplepos_t snap_to_marker (samplepos_t presnap,
ARDOUR::RoundMode direction = ARDOUR::RoundNearest);

View file

@ -347,9 +347,9 @@ Editor::do_import (vector<string> paths,
SrcQuality quality,
MidiTrackNameSource midi_track_name_source,
MidiTempoMapDisposition smf_tempo_disposition,
samplepos_t& pos,
timepos_t& pos,
ARDOUR::PluginInfoPtr instrument,
bool with_markers)
bool with_markers)
{
boost::shared_ptr<Track> track;
vector<string> to_import;
@ -502,11 +502,7 @@ Editor::do_import (vector<string> paths,
}
void
Editor::do_embed (vector<string> paths,
ImportDisposition import_as,
ImportMode mode,
samplepos_t& pos,
ARDOUR::PluginInfoPtr instrument)
Editor::do_embed (vector<string> paths, ImportDisposition import_as, ImportMode mode, timepos_t& pos, ARDOUR::PluginInfoPtr instrument)
{
boost::shared_ptr<Track> track;
bool check_sample_rate = true;

View file

@ -390,16 +390,17 @@ Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context
}
bool
Editor::idle_drop_paths (vector<string> paths, samplepos_t sample, double ypos, bool copy)
Editor::idle_drop_paths (vector<string> paths, timepos_t sample, double ypos, bool copy)
{
drop_paths_part_two (paths, sample, ypos, copy);
return false;
}
void
Editor::drop_paths_part_two (const vector<string>& paths, samplepos_t sample, double ypos, bool copy)
Editor::drop_paths_part_two (const vector<string>& paths, timepos_t const & p, double ypos, bool copy)
{
RouteTimeAxisView* tv;
timepos_t pos (p);
/* MIDI files must always be imported, because we consider them
* writable. So split paths into two vectors, and follow the import
@ -423,13 +424,13 @@ Editor::drop_paths_part_two (const vector<string>& paths, samplepos_t sample, do
/* drop onto canvas background: create new tracks */
InstrumentSelector is; // instantiation builds instrument-list and sets default.
do_import (midi_paths, Editing::ImportDistinctFiles, ImportAsTrack, SrcBest, SMFTrackName, SMFTempoIgnore, sample, is.selected_instrument(), false);
do_import (midi_paths, Editing::ImportDistinctFiles, ImportAsTrack, SrcBest, SMFTrackName, SMFTempoIgnore, pos, is.selected_instrument(), false);
if (UIConfiguration::instance().get_only_copy_imported_files() || copy) {
do_import (audio_paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack,
SrcBest, SMFTrackName, SMFTempoIgnore, sample);
SrcBest, SMFTrackName, SMFTempoIgnore, pos);
} else {
do_embed (audio_paths, Editing::ImportDistinctFiles, ImportAsTrack, sample);
do_embed (audio_paths, Editing::ImportDistinctFiles, ImportAsTrack, pos);
}
} else if ((tv = dynamic_cast<RouteTimeAxisView*> (tvp.first)) != 0) {
@ -441,13 +442,13 @@ Editor::drop_paths_part_two (const vector<string>& paths, samplepos_t sample, do
selection->set (tv);
do_import (midi_paths, Editing::ImportSerializeFiles, ImportToTrack,
SrcBest, SMFTrackName, SMFTempoIgnore, sample);
SrcBest, SMFTrackName, SMFTempoIgnore, pos);
if (UIConfiguration::instance().get_only_copy_imported_files() || copy) {
do_import (audio_paths, Editing::ImportSerializeFiles, Editing::ImportToTrack,
SrcBest, SMFTrackName, SMFTempoIgnore, sample, boost::shared_ptr<PluginInfo>(), false);
SrcBest, SMFTrackName, SMFTempoIgnore, pos, boost::shared_ptr<PluginInfo>(), false);
} else {
do_embed (audio_paths, Editing::ImportSerializeFiles, ImportToTrack, sample);
do_embed (audio_paths, Editing::ImportSerializeFiles, ImportToTrack, pos);
}
}
}
@ -472,7 +473,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
ev.button.x = x;
ev.button.y = y;
MusicSample when (window_event_sample (&ev, 0, &cy), 0);
timepos_t when (window_event_sample (&ev, 0, &cy));
snap_to (when);
bool copy = ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY);
@ -483,7 +484,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
*/
Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &Editor::idle_drop_paths), paths, when.sample, cy, copy));
#else
drop_paths_part_two (paths, when.sample, cy, copy);
drop_paths_part_two (paths, when, cy, copy);
#endif
}
@ -602,15 +603,15 @@ Editor::autoscroll_active () const
return autoscroll_connection.connected ();
}
std::pair <samplepos_t,samplepos_t>
std::pair <timepos_t,timepos_t>
Editor::session_gui_extents (bool use_extra) const
{
if (!_session) {
return std::pair <samplepos_t,samplepos_t>(max_samplepos,0);
return std::make_pair (timepos_t::max (Temporal::AudioTime), timepos_t (0));
}
samplecnt_t session_extent_start = _session->current_start_sample();
samplecnt_t session_extent_end = _session->current_end_sample();
timepos_t session_extent_start (_session->current_start_sample());
timepos_t session_extent_end (_session->current_end_sample());
/* calculate the extents of all regions in every playlist
* NOTE: we should listen to playlists, and cache these values so we don't calculate them every time.
@ -619,13 +620,14 @@ Editor::session_gui_extents (bool use_extra) const
boost::shared_ptr<RouteList> rl = _session->get_routes();
for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*r);
if (!tr) {
continue;
}
if (tr->presentation_info ().hidden ()) {
continue;
}
pair<samplepos_t, samplepos_t> e = tr->playlist()->get_extent ();
pair<timepos_t, timepos_t> e = tr->playlist()->get_extent ();
if (e.first == e.second) {
/* no regions present */
continue;
@ -641,19 +643,18 @@ Editor::session_gui_extents (bool use_extra) const
if (use_extra) {
samplecnt_t const extra = UIConfiguration::instance().get_extra_ui_extents_time() * 60 * _session->nominal_sample_rate();
session_extent_end += extra;
session_extent_start -= extra;
session_extent_start.shift_earlier (extra);
}
/* range-check */
if (session_extent_end > max_samplepos) {
session_extent_end = max_samplepos;
if (session_extent_end >= timepos_t::max (Temporal::AudioTime)) {
session_extent_end = timepos_t::max (Temporal::AudioTime);
}
if (session_extent_start < 0) {
session_extent_start = 0;
if (session_extent_start.negative()) {
session_extent_start = timepos_t (0);
}
std::pair <samplepos_t,samplepos_t> ret (session_extent_start, session_extent_end);
return ret;
return std::make_pair (session_extent_start, session_extent_end);
}
bool

View file

@ -2026,7 +2026,7 @@ RegionMoveDrag::finished_no_copy (
rv->region()->set_position (where.sample, 0);
} else {
/* move by music offset */
rv->region()->set_position_music (rv->region()->quarter_note() - qn_delta);
rv->region()->set_position (rv->region()->quarter_note() - qn_delta);
}
}
_editor->session()->add_command (new StatefulDiffCommand (rv->region()));
@ -6091,7 +6091,7 @@ NoteDrag::aborted (bool)
}
/** Make an AutomationRangeDrag for lines in an AutomationTimeAxisView */
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, list<AudioRange> const & r)
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, list<TimelineRange> const & r)
: Drag (editor, atv->base_item ())
, _ranges (r)
, _y_origin (atv->y_position())
@ -6103,7 +6103,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView
}
/** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list<RegionView*> const & v, list<AudioRange> const & r, double y_origin, double y_height)
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list<RegionView*> const & v, list<TimelineRange> const & r, double y_origin, double y_height)
: Drag (editor, v.front()->get_canvas_group ())
, _ranges (r)
, _y_origin (y_origin)
@ -6151,8 +6151,8 @@ AutomationRangeDrag::setup (list<boost::shared_ptr<AutomationLine> > const & lin
r.second = max_samplepos;
}
/* check this range against all the AudioRanges that we are using */
list<AudioRange>::const_iterator k = _ranges.begin ();
/* check this range against all the TimelineRanges that we are using */
list<TimelineRange>::const_iterator k = _ranges.begin ();
while (k != _ranges.end()) {
if (k->coverage (r.first, r.second) != Evoral::OverlapNone) {
break;
@ -6228,7 +6228,7 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move)
if (!_ranges.empty()) {
/* add guard points */
for (list<AudioRange>::const_iterator i = _ranges.begin(); i != _ranges.end(); ++i) {
for (list<TimelineRange>::const_iterator i = _ranges.begin(); i != _ranges.end(); ++i) {
samplecnt_t const half = (i->start + i->end) / 2;
@ -6308,7 +6308,7 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move)
double const w = i->line->time_converter().to ((*p->model())->when) + i->line->time_converter().origin_b ();
/* see if it's inside a range */
list<AudioRange>::const_iterator k = _ranges.begin ();
list<TimelineRange>::const_iterator k = _ranges.begin ();
while (k != _ranges.end() && (k->start >= w || k->end <= w)) {
++k;
}

View file

@ -1310,8 +1310,8 @@ private:
class AutomationRangeDrag : public Drag
{
public:
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::AudioRange> const &);
AutomationRangeDrag (Editor *, std::list<RegionView*> const &, std::list<ARDOUR::AudioRange> const &, double y_origin, double y_height);
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::TimelineRange> const &);
AutomationRangeDrag (Editor *, std::list<RegionView*> const &, std::list<ARDOUR::TimelineRange> const &, double y_origin, double y_height);
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
@ -1327,7 +1327,7 @@ private:
double y_fraction (double global_y_position) const;
double value (boost::shared_ptr<ARDOUR::AutomationList> list, double x) const;
std::list<ARDOUR::AudioRange> _ranges;
std::list<ARDOUR::TimelineRange> _ranges;
/** A line that is part of the drag */
struct Line {

View file

@ -118,7 +118,7 @@ Editor::loudness_assistant (bool range_selection)
samplepos_t start, end;
TimeSelection const& ts (get_selection().time);
if (range_selection && !ts.empty ()) {
start = ts.start();
start = ts.start_sample();
end = ts.end_sample();
} else {
start = _session->current_start_sample();
@ -158,7 +158,7 @@ Editor::measure_master_loudness (samplepos_t start, samplepos_t end, bool is_ran
return;
}
ARDOUR::AudioRange ar (start, end, 0);
ARDOUR::TimelineRange ar (timepos_t (start), timepos_t (end), 0);
LoudnessDialog ld (_session, ar, is_range_selection);
@ -320,9 +320,9 @@ Editor::bounce_region_selection (bool with_processing)
boost::shared_ptr<Region> r;
if (with_processing) {
r = track->bounce_range (region->position(), region->position() + region->length(), itt, track->main_outs(), false, bounce_name);
r = track->bounce_range (region->position_sample(), region->position_sample() + region->length_samples(), itt, track->main_outs(), false, bounce_name);
} else {
r = track->bounce_range (region->position(), region->position() + region->length(), itt, boost::shared_ptr<Processor>(), false, bounce_name);
r = track->bounce_range (region->position_sample(), region->position_sample() + region->length_samples(), itt, boost::shared_ptr<Processor>(), false, bounce_name);
}
}
}
@ -347,7 +347,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
/* don't do duplicate of the entire source if that's what is going on here */
if (region->start() == 0 && region->length() == region->source_length(0)) {
if (region->nt_start().zero() && region->nt_length() == region->source_length(0)) {
/* XXX should link(2) to create a new inode with "path" */
return true;
}
@ -396,8 +396,8 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
}
to_read = region->length();
pos = region->position();
to_read = region->length_samples();
pos = region->position_sample();
while (to_read) {
samplepos_t this_time;
@ -475,14 +475,14 @@ Editor::write_audio_selection (TimeSelection& ts)
}
bool
Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list<AudioRange>& range)
Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list<TimelineRange>& range)
{
boost::shared_ptr<AudioFileSource> fs;
const samplepos_t chunk_size = 4096;
samplepos_t nframes;
timecnt_t nframes;
Sample buf[chunk_size];
gain_t gain_buffer[chunk_size];
samplepos_t pos;
timepos_t pos;
char s[PATH_MAX+1];
uint32_t cnt;
string path;
@ -529,15 +529,14 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
}
for (list<AudioRange>::iterator i = range.begin(); i != range.end();) {
for (list<TimelineRange>::iterator i = range.begin(); i != range.end();) {
nframes = (*i).length();
pos = (*i).start;
pos = (*i).start();
while (nframes) {
samplepos_t this_time;
while (nframes.positive()) {
this_time = min (nframes, chunk_size);
timecnt_t this_time = min (nframes, timecnt_t (chunk_size));
for (uint32_t n=0; n < channels; ++n) {
@ -547,7 +546,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
break;
}
if (fs->write (buf, this_time) != this_time) {
if (fs->write (buf, this_time.samples()) != this_time.samples()) {
goto error_out;
}
}
@ -556,24 +555,24 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
pos += this_time;
}
list<AudioRange>::iterator tmp = i;
list<TimelineRange>::iterator tmp = i;
++tmp;
if (tmp != range.end()) {
/* fill gaps with silence */
nframes = (*tmp).start - (*i).end;
nframes = (*i).end().distance ((*tmp).start());
while (nframes) {
while (nframes.positive()) {
samplepos_t this_time = min (nframes, chunk_size);
memset (buf, 0, sizeof (Sample) * this_time);
timecnt_t this_time = min (nframes, timecnt_t (chunk_size));
memset (buf, 0, sizeof (Sample) * this_time.samples());
for (uint32_t n=0; n < channels; ++n) {
fs = sources[n];
if (fs->write (buf, this_time) != this_time) {
if (fs->write (buf, this_time.samples()) != this_time.samples()) {
goto error_out;
}
}

View file

@ -46,27 +46,32 @@ using namespace Editing;
void
Editor::keyboard_selection_finish (bool /*add*/, Editing::EditIgnoreOption ign)
{
if (_session) {
MusicSample start (selection->time.start(), 0);
samplepos_t end;
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
end = _session->audible_sample();
} else {
end = get_preferred_edit_position(ign);
}
//if no tracks are selected and we're working from the keyboard, enable all tracks (_something_ has to be selected for any range selection)
if ( (_edit_point == EditAtPlayhead) && selection->tracks.empty() )
select_all_visible_lanes();
selection->set (start.sample, end);
//if session is playing a range, cancel that
if (_session->get_play_range())
_session->request_cancel_play_range();
if (!_session) {
return;
}
timepos_t start = selection->time.start_time();
timepos_t end;
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
end = _session->audible_sample();
} else {
end = get_preferred_edit_position(ign);
}
//snap the selection start/end
snap_to (start);
//if no tracks are selected and we're working from the keyboard, enable all tracks (_something_ has to be selected for any range selection)
if ( (_edit_point == EditAtPlayhead) && selection->tracks.empty() )
select_all_tracks();
selection->set (start, end);
//if session is playing a range, cancel that
if (_session->get_play_range()) {
_session->request_cancel_play_range();
}
}
void
@ -74,22 +79,22 @@ Editor::keyboard_selection_begin (Editing::EditIgnoreOption ign)
{
if (_session) {
MusicSample start (0, 0);
MusicSample end (selection->time.end_sample(), 0);
timepos_t start;
timepos_t end (selection->time.end_time());
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
start.sample = _session->audible_sample();
start = _session->audible_sample();
} else {
start.sample = get_preferred_edit_position(ign);
start = get_preferred_edit_position(ign);
}
//if there's not already a sensible selection endpoint, go "forever"
if (start.sample > end.sample) {
if (start > end ) {
#ifdef MIXBUS
// 4hours at most.
// This works around a visual glitch in red-bordered selection rect.
end.sample = start.sample + _session->nominal_sample_rate() * 60 * 60 * 4;
end = start + timepos_t (_session->nominal_sample_rate() * 60 * 60 * 4);
#else
end.sample = max_samplepos;
end = timepos_t::max (end.time_domain());
#endif
}
@ -97,7 +102,7 @@ Editor::keyboard_selection_begin (Editing::EditIgnoreOption ign)
if ( selection->tracks.empty() )
select_all_visible_lanes();
selection->set (start.sample, end.sample);
selection->set (start, end);
//if session is playing a range, cancel that
if (_session->get_play_range())

View file

@ -174,7 +174,7 @@ Editor::add_new_location_internal (Location* location)
}
location->name_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->position_lock_style_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->position_time_domain_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (*this, invalidator (*this), boost::bind (&Editor::location_flags_changed, this, location), gui_context());
pair<Location*,LocationMarkers*> newpair;
@ -214,7 +214,7 @@ Editor::location_changed (Location *location)
return;
}
if (location->position_lock_style() == MusicTime) {
if (location->position_time_domain() == Temporal::BeatTime) {
lam->set_name ("\u266B" + location->name ()); // BEAMED EIGHTH NOTES
} else {
lam->set_name (location->name ());
@ -278,7 +278,7 @@ Editor::check_marker_label (ArdourMarker* m)
/* Update just the available space between the previous marker and this one */
double const p = sample_to_pixel (m->position() - (*prev)->position());
double const p = sample_to_pixel ((*prev)->position().distance (m->position()).samples());
if (m->label_on_left()) {
(*prev)->set_right_label_limit (p / 2);
@ -297,7 +297,7 @@ Editor::check_marker_label (ArdourMarker* m)
/* Update just the available space between this marker and the next */
double const p = sample_to_pixel ((*next)->position() - m->position());
double const p = sample_to_pixel (m->position().distance ((*next)->position()).samples());
if ((*next)->label_on_left()) {
m->set_right_label_limit (p / 2);
@ -354,7 +354,7 @@ Editor::update_marker_labels (ArdourCanvas::Container* group)
while (i != sorted.end()) {
if (prev != sorted.end()) {
double const p = sample_to_pixel ((*i)->position() - (*prev)->position());
double const p = sample_to_pixel ((*prev)->position().distance ((*i)->position()).samples());
if ((*prev)->label_on_left()) {
(*i)->set_left_label_limit (p);
@ -365,7 +365,7 @@ Editor::update_marker_labels (ArdourCanvas::Container* group)
}
if (next != sorted.end()) {
double const p = sample_to_pixel ((*next)->position() - (*i)->position());
double const p = sample_to_pixel ((*i)->position().distance ((*next)->position()).samples());
if ((*next)->label_on_left()) {
(*i)->set_right_label_limit (p / 2);
@ -613,12 +613,12 @@ Editor::LocationMarkers::set_name (const string& str)
}
void
Editor::LocationMarkers::set_position (samplepos_t startf,
samplepos_t endf)
Editor::LocationMarkers::set_position (timepos_t const & startt,
timepos_t const & endt)
{
start->set_position (startf);
if (end) {
end->set_position (endf);
start->set_position (startt);
if (!endt.zero()) {
end->set_position (endt);
}
}
@ -678,7 +678,8 @@ Editor::mouse_add_new_marker (samplepos_t where, bool is_cd)
if (!choose_new_marker_name(markername)) {
return;
}
Location *location = new Location (*_session, where, where, markername, (Location::Flags) flags, get_grid_music_divisions (0));
#warning NUTEMPO how do we make the position be in musical time from a mouse event?
Location *location = new Location (*_session, timepos_t (where), timepos_t (where), markername, (Location::Flags) flags);
begin_reversible_command (_("add marker"));
XMLNode &before = _session->locations()->get_state();
@ -745,7 +746,8 @@ Editor::mouse_add_new_range (samplepos_t where)
string name;
_session->locations()->next_available_name (name, _("range"));
Location* loc = new Location (*_session, where, end, name, Location::IsRangeMarker);
#warning NUTEMPO how do we get music time here from a mouse event?
Location* loc = new Location (*_session, timepos_t (where), timepos_t (end), name, Location::IsRangeMarker);
begin_reversible_command (_("new range marker"));
XMLNode& before = _session->locations()->get_state ();
@ -989,7 +991,7 @@ Editor::build_marker_menu (Location* loc)
items.push_back (CheckMenuElem (_("Glue to Bars and Beats")));
Gtk::CheckMenuItem* glue_item = static_cast<Gtk::CheckMenuItem*> (&items.back());
glue_item->set_active (loc->position_lock_style() == MusicTime);
glue_item->set_active (loc->position_time_domain() == Temporal::BeatTime);
glue_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_glue));
@ -1025,7 +1027,7 @@ Editor::build_range_marker_menu (Location* loc, bool loop_or_punch, bool session
items.push_back (CheckMenuElem (_("Glue to Bars and Beats")));
Gtk::CheckMenuItem* glue_item = static_cast<Gtk::CheckMenuItem*> (&items.back());
glue_item->set_active (loc->position_lock_style() == MusicTime);
glue_item->set_active (loc->position_time_domain() == Temporal::BeatTime);
glue_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_glue));
items.push_back (SeparatorElem());
@ -1202,7 +1204,7 @@ Editor::marker_menu_select_all_selectables_using_range ()
bool is_start;
if (((l = find_location_from_marker (marker, is_start)) != 0) && (l->end() > l->start())) {
select_all_within (l->start(), l->end() - 1, 0, DBL_MAX, track_views, Selection::Set, false);
select_all_within (l->start(), l->end().decrement(), 0, DBL_MAX, track_views, Selection::Set, false);
}
}
@ -1242,15 +1244,15 @@ Editor::marker_menu_play_from ()
if ((l = find_location_from_marker (marker, is_start)) != 0) {
if (l->is_mark()) {
_session->request_locate (l->start(), MustRoll);
_session->request_locate (l->start_sample(), MustRoll);
}
else {
//_session->request_bounded_roll (l->start(), l->end());
//_session->request_bounded_roll (l->start_sample(), l->end());
if (is_start) {
_session->request_locate (l->start(), MustRoll);
_session->request_locate (l->start_sample(), MustRoll);
} else {
_session->request_locate (l->end(), MustRoll);
_session->request_locate (l->end_sample(), MustRoll);
}
}
}
@ -1272,13 +1274,13 @@ Editor::marker_menu_set_playhead ()
if ((l = find_location_from_marker (marker, is_start)) != 0) {
if (l->is_mark()) {
_session->request_locate (l->start(), MustStop);
_session->request_locate (l->start_sample(), MustStop);
}
else {
if (is_start) {
_session->request_locate (l->start(), MustStop);
_session->request_locate (l->start_sample(), MustStop);
} else {
_session->request_locate (l->end(), MustStop);
_session->request_locate (l->end_sample(), MustStop);
}
}
}
@ -1304,8 +1306,8 @@ Editor::marker_menu_range_to_next ()
return;
}
samplepos_t start;
samplepos_t end;
timepos_t start;
timepos_t end;
_session->locations()->marks_either_side (marker->position(), start, end);
if (end != max_samplepos) {
@ -1329,18 +1331,19 @@ Editor::marker_menu_set_from_playhead ()
Location* l;
bool is_start;
const int32_t divisions = get_grid_music_divisions (0);
if ((l = find_location_from_marker (marker, is_start)) != 0) {
#warning NUTEMPO what if the user wants musical time here?
if (l->is_mark()) {
l->set_start (_session->audible_sample (), false, true, divisions);
l->set_start (timepos_t (_session->audible_sample ()), false);
}
else {
if (is_start) {
l->set_start (_session->audible_sample (), false, true, divisions);
l->set_start (timepos_t (_session->audible_sample ()), false);
} else {
l->set_end (_session->audible_sample (), false, true, divisions);
l->set_end (timepos_t (_session->audible_sample ()), false);
}
}
}
@ -1368,9 +1371,9 @@ Editor::marker_menu_set_from_selection (bool /*force_regions*/)
} else {
if (!selection->time.empty()) {
l->set (selection->time.start(), selection->time.end_sample());
l->set (selection->time.start_time(), selection->time.end_time());
} else if (!selection->regions.empty()) {
l->set (selection->regions.start(), selection->regions.end_sample());
l->set (selection->regions.start_time(), selection->regions.end_time());
}
}
}
@ -1393,10 +1396,10 @@ Editor::marker_menu_play_range ()
if ((l = find_location_from_marker (marker, is_start)) != 0) {
if (l->is_mark()) {
_session->request_locate (l->start(), MustRoll);
_session->request_locate (l->start().samples(), MustRoll);
}
else {
_session->request_bounded_roll (l->start(), l->end());
_session->request_bounded_roll (l->start().samples(), l->end().samples());
}
}
@ -1418,7 +1421,7 @@ Editor::marker_menu_loop_range ()
if ((l = find_location_from_marker (marker, is_start)) != 0) {
if (l != transport_loop_location()) {
cerr << "Set loop\n";
set_loop_range (l->start(), l->end(), _("loop range from marker"));
set_loop_range (l->start().samples(), l->end().samples(), _("loop range from marker"));
} else {
cerr << " at TL\n";
}
@ -1439,18 +1442,18 @@ Editor::marker_menu_zoom_to_range ()
return;
}
samplecnt_t const extra = l->length() * 0.05;
samplepos_t a = l->start ();
if (a >= extra) {
a -= extra;
timecnt_t const extra = l->length() * Temporal::ratio_t (5, 100);
timepos_t a = l->start ();
if (a >= timepos_t (extra)) {
a.shift_earlier (extra);
}
samplepos_t b = l->end ();
if (b < (max_samplepos - extra)) {
timepos_t b = l->end ();
if (b < (extra.distance (timepos_t::max (extra.time_domain())))) {
b += extra;
}
temporal_zoom_by_sample (a, b);
temporal_zoom_by_sample (a.samples(), b.samples());
}
void

View file

@ -1236,7 +1236,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
if (boost::dynamic_pointer_cast<AudioPlaylist> (playlist) == 0) {
continue;
}
for (list<AudioRange>::const_iterator j = selection->time.begin(); j != selection->time.end(); ++j) {
for (list<TimelineRange>::const_iterator j = selection->time.begin(); j != selection->time.end(); ++j) {
boost::shared_ptr<RegionList> rl = playlist->regions_touched (j->start, j->end);
for (RegionList::iterator ir = rl->begin(); ir != rl->end(); ++ir) {
RegionView* rv;

View file

@ -2723,8 +2723,8 @@ Editor::play_selection ()
if (!get_selection_extents (start, end))
return;
AudioRange ar (start, end, 0);
list<AudioRange> lar;
TimelineRange ar (start, end, 0);
list<TimelineRange> lar;
lar.push_back (ar);
_session->request_play_range (&lar, true);
@ -2767,8 +2767,8 @@ Editor::play_with_preroll ()
end = end + preroll; //"post-roll"
AudioRange ar (start, end, 0);
list<AudioRange> lar;
TimelineRange ar (start, end, 0);
list<TimelineRange> lar;
lar.push_back (ar);
_session->request_play_range (&lar, true);
@ -3152,10 +3152,10 @@ Editor::new_region_from_selection ()
}
static void
add_if_covered (RegionView* rv, const AudioRange* ar, RegionSelection* rs)
add_if_covered (RegionView* rv, const TimelineRange* ar, RegionSelection* rs)
{
switch (rv->region()->coverage (ar->start, ar->end - 1)) {
// n.b. -1 because AudioRange::end is one past the end, but coverage expects inclusive ranges
// n.b. -1 because TimelineRange::end is one past the end, but coverage expects inclusive ranges
case Evoral::OverlapNone:
break;
default:
@ -3229,7 +3229,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
/* XXX need to consider musical time selections here at some point */
for (list<AudioRange>::const_iterator t = ts.begin(); t != ts.end(); ++t) {
for (list<TimelineRange>::const_iterator t = ts.begin(); t != ts.end(); ++t) {
if (!in_command) {
begin_reversible_command (_("separate"));
@ -3313,7 +3313,7 @@ Editor::separate_region_from_selection ()
if (get_edit_op_range (start, end)) {
AudioRange ar (start, end, 1);
TimelineRange ar (start, end, 1);
TimeSelection ts;
ts.push_back (ar);
@ -3347,7 +3347,7 @@ Editor::separate_regions_using_location (Location& loc)
return;
}
AudioRange ar (loc.start(), loc.end(), 1);
TimelineRange ar (loc.start(), loc.end(), 1);
TimeSelection ts;
ts.push_back (ar);
@ -3437,7 +3437,7 @@ Editor::crop_region_to_selection ()
if (!selection->time.empty()) {
begin_reversible_command (_("Crop Regions to Time Selection"));
for (std::list<AudioRange>::iterator i = selection->time.begin(); i != selection->time.end(); ++i) {
for (std::list<TimelineRange>::iterator i = selection->time.begin(); i != selection->time.end(); ++i) {
crop_region_to ((*i).start, (*i).end);
}
commit_reversible_command();
@ -4207,8 +4207,8 @@ Editor::bounce_range_selection (bool replace, bool enable_processing)
if (replace) {
/*remove the edxisting regions under the edit range*/
list<AudioRange> ranges;
ranges.push_back (AudioRange (start, start+cnt, 0));
list<TimelineRange> ranges;
ranges.push_back (TimelineRange (start, start+cnt, 0));
playlist->cut (ranges); // discard result
/*SPECIAL CASE: we are bouncing to a new Source *AND* replacing the existing range on the timeline (consolidate)*/
@ -8163,8 +8163,8 @@ Editor::remove_time (samplepos_t pos, samplecnt_t samples, InsertTimeOption opt,
in_command = true;
}
std::list<AudioRange> rl;
AudioRange ar(pos, pos+samples, 0);
std::list<TimelineRange> rl;
TimelineRange ar(pos, pos+samples, 0);
rl.push_back(ar);
pl->cut (rl);
pl->shift (pos, -samples, true, ignore_music_glue);

View file

@ -601,10 +601,11 @@ EditorRegions::clock_format_changed ()
}
void
EditorRegions::format_position (samplepos_t pos, char* buf, size_t bufsize, bool onoff)
EditorRegions::format_position (timepos_t const & p, char* buf, size_t bufsize, bool onoff)
{
Temporal::BBT_Time bbt;
Timecode::Time timecode;
samplepos_t pos (p.samples());
if (pos < 0) {
error << string_compose (_ ("EditorRegions::format_position: negative timecode position: %1"), pos) << endmsg;
@ -713,7 +714,7 @@ EditorRegions::populate_row (boost::shared_ptr<Region> region, TreeModel::Row co
if (all || what_changed.contains (Properties::locked)) {
populate_row_locked (region, row);
}
if (all || what_changed.contains (Properties::position_lock_style)) {
if (all || what_changed.contains (Properties::time_domain)) {
populate_row_glued (region, row);
}
if (all || what_changed.contains (Properties::muted)) {
@ -775,7 +776,7 @@ EditorRegions::populate_row_length (boost::shared_ptr<Region> region, TreeModel:
Temporal::BBT_Time bbt = map.bbt_at_beat (map.beat_at_sample (region->last_sample ()) - map.beat_at_sample (region->first_sample ()));
snprintf (buf, sizeof (buf), "%03d|%02d|%04d", bbt.bars, bbt.beats, bbt.ticks);
} else {
format_position (region->length (), buf, sizeof (buf));
format_position (timepos_t (region->nt_length ()), buf, sizeof (buf));
}
row[_columns.length] = buf;
@ -790,7 +791,7 @@ EditorRegions::populate_row_end (boost::shared_ptr<Region> region, TreeModel::Ro
if (region->last_sample () >= region->first_sample ()) {
char buf[16];
format_position (region->last_sample (), buf, sizeof (buf));
format_position (region->nt_last (), buf, sizeof (buf));
row[_columns.end] = buf;
} else {
row[_columns.end] = "empty";
@ -800,10 +801,10 @@ EditorRegions::populate_row_end (boost::shared_ptr<Region> region, TreeModel::Ro
void
EditorRegions::populate_row_position (boost::shared_ptr<Region> region, TreeModel::Row const& row)
{
row[_columns.position] = region->position ();
row[_columns.position] = region->nt_position ();
char buf[16];
format_position (region->position (), buf, sizeof (buf));
format_position (region->nt_position (), buf, sizeof (buf));
row[_columns.start] = buf;
}
@ -813,7 +814,7 @@ EditorRegions::populate_row_sync (boost::shared_ptr<Region> region, TreeModel::R
#ifndef SHOW_REGION_EXTRAS
return;
#endif
if (region->sync_position () == region->position ()) {
if (region->sync_position () == region->nt_position ()) {
row[_columns.sync] = _ ("Start");
} else if (region->sync_position () == (region->last_sample ())) {
row[_columns.sync] = _ ("End");
@ -863,7 +864,7 @@ EditorRegions::populate_row_locked (boost::shared_ptr<Region> region, TreeModel:
void
EditorRegions::populate_row_glued (boost::shared_ptr<Region> region, TreeModel::Row const& row)
{
if (region->position_lock_style () == MusicTime) {
if (region->position_time_domain () == Temporal::BeatTime) {
row[_columns.glued] = true;
} else {
row[_columns.glued] = false;
@ -890,7 +891,7 @@ EditorRegions::populate_row_name (boost::shared_ptr<Region> region, TreeModel::R
if (region->data_type() == DataType::MIDI) {
row[_columns.channels] = 0; /*TODO: some better recognition of midi regions*/
} else {
row[_columns.channels] = region->n_channels();
row[_columns.channels] = region->sources().size();
}
row[_columns.tags] = region->tags ();
@ -1027,8 +1028,8 @@ EditorRegions::drag_data_received (const RefPtr<Gdk::DragContext>& context,
}
if (_editor->convert_drop_to_paths (paths, context, x, y, data, info, dtime) == 0) {
samplepos_t pos = 0;
bool copy = ((context->get_actions () & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY);
timepos_t pos;
bool copy = ((context->get_actions () & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY);
if (UIConfiguration::instance ().get_only_copy_imported_files () || copy) {
_editor->do_import (paths, Editing::ImportDistinctFiles, Editing::ImportAsRegion,
@ -1232,7 +1233,7 @@ EditorRegions::glued_changed (std::string const& path)
boost::shared_ptr<ARDOUR::Region> region = (*i)[_columns.region];
if (region) {
/* `glued' means MusicTime, and we're toggling here */
region->set_position_lock_style ((*i)[_columns.glued] ? AudioTime : MusicTime);
region->set_position_time_domain ((*i)[_columns.glued] ? Temporal::AudioTime : Temporal::BeatTime);
}
}
}

View file

@ -99,7 +99,7 @@ private:
Gtk::TreeModelColumn<std::string> name;
Gtk::TreeModelColumn<int> channels;
Gtk::TreeModelColumn<std::string> tags;
Gtk::TreeModelColumn<samplepos_t> position;
Gtk::TreeModelColumn<Temporal::timepos_t> position;
Gtk::TreeModelColumn<std::string> start;
Gtk::TreeModelColumn<std::string> end;
Gtk::TreeModelColumn<std::string> length;
@ -158,7 +158,7 @@ private:
void show_context_menu (int button, int time);
void format_position (ARDOUR::samplepos_t pos, char* buf, size_t bufsize, bool onoff = true);
void format_position (Temporal::timepos_t const & pos, char* buf, size_t bufsize, bool onoff = true);
void add_region (boost::shared_ptr<ARDOUR::Region>);
void destroy_region (boost::shared_ptr<ARDOUR::Region>);

View file

@ -149,9 +149,9 @@ EditorSummary::render_background_image ()
/* compute start and end points for the summary */
std::pair<samplepos_t, samplepos_t> ext = _editor->session_gui_extents();
double theoretical_start = ext.first;
double theoretical_end = ext.second;
std::pair<timepos_t, timepos_t> ext = _editor->session_gui_extents();
double theoretical_start = ext.first.samples();
double theoretical_end = ext.second.samples();
/* the summary should encompass the full extent of everywhere we've visited since the session was opened */
if (_leftmost < theoretical_start)
@ -337,14 +337,14 @@ EditorSummary::render_region (RegionView* r, cairo_t* cr, double y) const
uint32_t const c = r->get_fill_color ();
cairo_set_source_rgb (cr, UINT_RGBA_R (c) / 255.0, UINT_RGBA_G (c) / 255.0, UINT_RGBA_B (c) / 255.0);
if (r->region()->position() > _start) {
cairo_move_to (cr, (r->region()->position() - _start) * _x_scale, y);
if (r->region()->position_sample() > _start) {
cairo_move_to (cr, (r->region()->position_sample() - _start) * _x_scale, y);
} else {
cairo_move_to (cr, 0, y);
}
if ((r->region()->position() + r->region()->length()) > _start) {
cairo_line_to (cr, ((r->region()->position() - _start + r->region()->length())) * _x_scale, y);
if ((r->region()->nt_position() + r->region()->nt_length()) > _start) {
cairo_line_to (cr, ((r->region()->position_sample() - _start + r->region()->length_samples())) * _x_scale, y);
} else {
cairo_line_to (cr, 0, y);
}

View file

@ -103,7 +103,7 @@ Editor::embed_audio_from_video (std::string path, samplepos_t n, bool lock_posit
if (ok && track) {
if (lock_position_to_video) {
boost::shared_ptr<ARDOUR::Playlist> pl = track->playlist();
pl->find_next_region(n, ARDOUR::End, 0)->set_video_locked(true);
pl->find_next_region (Temporal::timepos_t (n), ARDOUR::End, 0)->set_video_locked (true);
}
_session->save_state ("", true);
}

View file

@ -58,7 +58,7 @@ using namespace ArdourWidgets;
bool LoudnessDialog::_first_time = true;
CLoudnessPreset LoudnessDialog::_last_preset;
LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
LoudnessDialog::LoudnessDialog (Session* s, TimelineRange const& ar, bool as)
: ArdourDialog (as ? _("Loudness Assistant") : _("Loudness Analyzer and Normalizer"))
, _lp (false)
, _session (s)

View file

@ -36,7 +36,7 @@
#include "loudness_settings.h"
namespace ARDOUR {
class AudioRange;
class TimelineRange;
class ExportAnalysis;
class ExportStatus;
class PluginInsert;
@ -47,7 +47,7 @@ namespace ARDOUR {
class LoudnessDialog : public ArdourDialog
{
public:
LoudnessDialog (ARDOUR::Session*, ARDOUR::AudioRange const&, bool);
LoudnessDialog (ARDOUR::Session*, ARDOUR::TimelineRange const&, bool);
int run ();
float gain_db () const;
@ -86,7 +86,7 @@ private:
static CLoudnessPreset _last_preset;
ARDOUR::Session* _session;
ARDOUR::AudioRange const& _range;
ARDOUR::TimelineRange const& _range;
boost::shared_ptr<ARDOUR::ExportStatus> _status;
bool _autostart;

View file

@ -852,7 +852,7 @@ LuaInstance::register_classes (lua_State* L)
.addFunction ("regionlist", &RegionSelection::regionlist) // XXX check windows binding (libardour)
.endClass ()
.deriveClass <TimeSelection, std::list<ARDOUR::AudioRange> > ("TimeSelection")
.deriveClass <TimeSelection, std::list<ARDOUR::TimelineRange> > ("TimeSelection")
.addFunction ("start", &TimeSelection::start)
.addFunction ("end_sample", &TimeSelection::end_sample)
.addFunction ("length", &TimeSelection::length)

View file

@ -71,7 +71,7 @@ void ArdourMarker::setup_sizes(const double timebar_height)
}
ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Container& parent, guint32 rgba, const string& annotation,
Type type, samplepos_t sample, bool handle_events, RegionView* rv)
Type type, timepos_t const & pos, bool handle_events, RegionView* rc)
: editor (ed)
, _parent (&parent)
@ -267,8 +267,8 @@ ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Container& parent, g
}
sample_position = sample;
unit_position = editor.sample_to_pixel (sample);
_position = pos;
unit_position = editor.sample_to_pixel (pos.samples());
unit_position -= _shift;
group = new ArdourCanvas::Container (&parent, ArdourCanvas::Duple (unit_position, 1));
@ -530,18 +530,18 @@ ArdourMarker::setup_name_display ()
}
void
ArdourMarker::set_position (samplepos_t sample)
ArdourMarker::set_position (timepos_t const & pos)
{
unit_position = editor.sample_to_pixel (sample) - _shift;
unit_position = editor.sample_to_pixel (pos.samples()) - _shift;
group->set_x_position (unit_position);
setup_line ();
sample_position = sample;
_position = pos;
}
void
ArdourMarker::reposition ()
{
set_position (sample_position);
set_position (_position);
}
void
@ -633,7 +633,9 @@ ArdourMarker::set_right_label_limit (double p)
TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Container& parent, guint32 rgba, const string& text,
ARDOUR::TempoSection& temp)
: ArdourMarker (editor, parent, rgba, text, Tempo, temp.sample(), false),
#warning NUTEMPO needs new tempo map
// : ArdourMarker (editor, parent, rgba, text, Tempo, temp.sample(), false),
: ArdourMarker (editor, parent, rgba, text, Tempo, timepos_t (), false),
_tempo (temp)
{
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_marker_event), group, this));
@ -667,7 +669,10 @@ TempoMarker::update_height_mark (const double ratio)
MeterMarker::MeterMarker (PublicEditor& editor, ArdourCanvas::Container& parent, guint32 rgba, const string& text,
ARDOUR::MeterSection& m)
: ArdourMarker (editor, parent, rgba, text, Meter, m.sample(), false),
#warning NUTEMPO needs new tempo map
// : ArdourMarker (editor, parent, rgba, text, Meter, m.sample(), false),
: ArdourMarker (editor, parent, rgba, text, Meter, timepos_t(), false),
_meter (m)
{
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_meter_marker_event), group, this));

View file

@ -67,8 +67,8 @@ public:
ArdourMarker (PublicEditor& editor, ArdourCanvas::Container &, guint32 rgba, const std::string& text, Type,
samplepos_t sample = 0, bool handle_events = true, RegionView* rv = 0);
ARDOUR::timepos_t const & position, bool handle_events = true, RegionView* rv = 0);
virtual ~ArdourMarker ();
static PBD::Signal1<void,ArdourMarker*> CatchDeletion;
@ -82,13 +82,13 @@ public:
void set_show_line (bool);
void set_line_height (double);
void set_position (samplepos_t);
void set_position (Temporal::timepos_t const &);
void set_name (const std::string&);
void set_points_color (uint32_t rgba);
void set_color_rgba (uint32_t rgba);
void setup_line ();
samplepos_t position() const { return sample_position; }
ARDOUR::timepos_t position() const { return _position; }
ArdourCanvas::Container * get_parent() { return _parent; }
void reparent (ArdourCanvas::Container & parent);
@ -126,7 +126,7 @@ protected:
std::string _name;
double unit_position;
samplepos_t sample_position;
ARDOUR::timepos_t _position;
double _shift;
Type _type;
int name_height;

View file

@ -33,8 +33,7 @@ public:
MidiAutomationLine (const std::string&, TimeAxisView&, ArdourCanvas::Item&,
boost::shared_ptr<ARDOUR::AutomationList>,
boost::shared_ptr<ARDOUR::MidiRegion>,
Evoral::Parameter,
Evoral::TimeConverter<double, ARDOUR::samplepos_t>* converter = 0);
Evoral::Parameter);
MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();

View file

@ -2834,46 +2834,6 @@ MidiRegionView::get_end_position_pixels()
return trackview.editor().sample_to_pixel(sample);
}
samplepos_t
MidiRegionView::source_beats_to_absolute_samples(Temporal::Beats beats) const
{
/* the time converter will return the sample corresponding to `beats'
relative to the start of the source. The start of the source
is an implied position given by region->position - region->start
*/
const samplepos_t source_start = _region->position() - _region->start();
return source_start + _source_relative_time_converter.to (beats);
}
Temporal::Beats
MidiRegionView::absolute_samples_to_source_beats(samplepos_t samples) const
{
/* the `samples' argument needs to be converted into a sample count
relative to the start of the source before being passed in to the
converter.
*/
const samplepos_t source_start = _region->position() - _region->start();
return _source_relative_time_converter.from (samples - source_start);
}
samplepos_t
MidiRegionView::region_beats_to_region_samples(Temporal::Beats beats) const
{
return _region_relative_time_converter.to(beats);
}
Temporal::Beats
MidiRegionView::region_samples_to_region_beats(samplepos_t samples) const
{
return _region_relative_time_converter.from(samples);
}
double
MidiRegionView::region_samples_to_region_beats_double (samplepos_t samples) const
{
return _region_relative_time_converter_double.from(samples);
}
void
MidiRegionView::begin_resizing (bool /*at_front*/)
{

View file

@ -271,46 +271,13 @@ public:
*/
double snap_to_pixel(double x, bool ensure_snap = false);
/** Snap a region relative pixel coordinate to sample units.
/** Snap a region relative pixel coordinate to time units.
* @param x a pixel coordinate relative to region start
* @param ensure_snap ignore SnapOff and magnetic snap.
* Required for inverting snap logic with modifier keys and snap delta calculation.
* @return the snapped samplepos_t coordinate relative to region start
* @return the snapped timepos_t coordinate relative to region start
*/
samplepos_t snap_pixel_to_sample(double x, bool ensure_snap = false);
/** Convert a timestamp in beats into samples (both relative to region position) */
samplepos_t region_beats_to_region_samples(Temporal::Beats beats) const;
/** Convert a timestamp in beats into absolute samples */
samplepos_t region_beats_to_absolute_samples(Temporal::Beats beats) const {
return _region->position() + region_beats_to_region_samples (beats);
}
/** Convert a timestamp in samples to beats (both relative to region position) */
Temporal::Beats region_samples_to_region_beats(samplepos_t) const;
double region_samples_to_region_beats_double(samplepos_t) const;
/** Convert a timestamp in beats measured from source start into absolute samples */
samplepos_t source_beats_to_absolute_samples(Temporal::Beats beats) const;
/** Convert a timestamp in beats measured from source start into region-relative samples */
samplepos_t source_beats_to_region_samples(Temporal::Beats beats) const {
return source_beats_to_absolute_samples (beats) - _region->position();
}
/** Convert a timestamp in absolute samples to beats measured from source start*/
Temporal::Beats absolute_samples_to_source_beats(samplepos_t) const;
ARDOUR::BeatsSamplesConverter const & region_relative_time_converter () const {
return _region_relative_time_converter;
}
ARDOUR::BeatsSamplesConverter const & source_relative_time_converter () const {
return _source_relative_time_converter;
}
ARDOUR::BeatsSamplesConverter const & region_relative_time_converter_double () const {
return _region_relative_time_converter;
}
double session_relative_qn (double qn) const;
Temporal::timepos_t snap_pixel_to_time (double x, bool ensure_snap = false);
void goto_previous_note (bool add_to_selection);
void goto_next_note (bool add_to_selection);

View file

@ -95,7 +95,7 @@ public:
void get_regions_with_selected_data (RegionSelection&);
bool paste (ARDOUR::samplepos_t, const Selection&, PasteContext& ctx, const int32_t sub_num);
bool paste (Temporal::timepos_t const &, const Selection&, PasteContext& ctx);
ARDOUR::NoteMode note_mode() const { return _note_mode; }
ARDOUR::ColorMode color_mode() const { return _color_mode; }

View file

@ -984,7 +984,7 @@ Mixer_UI::fan_out (boost::weak_ptr<Route> wr, bool to_busses, bool group)
boost::shared_ptr<AutomationControl> msac = route->master_send_enable_controllable ();
if (msac) {
msac->start_touch (msac->session().transport_sample());
msac->start_touch (timepos_t (msac->session().transport_sample()));
msac->set_value (0, PBD::Controllable::NoGroup);
}
@ -3635,7 +3635,7 @@ Mixer_UI::control_action (boost::shared_ptr<T> (Stripable::*get_control)() const
if (s) {
ac = (s.get()->*get_control)();
if (ac) {
ac->start_touch (_session->audible_sample ());
ac->start_touch (timepos_t (_session->audible_sample ()));
cl->push_back (ac);
if (!have_val) {
val = !ac->get_value();

View file

@ -152,7 +152,7 @@ public:
* Snap a value according to the current snap setting.
* ensure_snap overrides SnapOff and magnetic snap
*/
virtual void snap_to (ARDOUR::MusicSample& first,
virtual void snap_to (Temporal::timepos_t & first,
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
bool ensure_snap = false) = 0;
@ -261,10 +261,10 @@ public:
/** Import existing media */
virtual void do_import (std::vector<std::string> paths, Editing::ImportDisposition, Editing::ImportMode mode, ARDOUR::SrcQuality,
ARDOUR::MidiTrackNameSource, ARDOUR::MidiTempoMapDisposition, samplepos_t&,
ARDOUR::MidiTrackNameSource, ARDOUR::MidiTempoMapDisposition, Temporal::timepos_t&,
boost::shared_ptr<ARDOUR::PluginInfo> instrument = boost::shared_ptr<ARDOUR::PluginInfo>(),
bool with_markers = false) = 0;
virtual void do_embed (std::vector<std::string> paths, Editing::ImportDisposition, Editing::ImportMode mode, samplepos_t&,
virtual void do_embed (std::vector<std::string> paths, Editing::ImportDisposition, Editing::ImportMode mode, Temporal::timepos_t&,
boost::shared_ptr<ARDOUR::PluginInfo> instrument = boost::shared_ptr<ARDOUR::PluginInfo>()) = 0;
/** Open main export dialog */
@ -357,10 +357,10 @@ public:
virtual void mouse_add_new_marker (samplepos_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 samplecnt_t get_nudge_distance (samplepos_t pos, samplecnt_t& next) = 0;
virtual samplecnt_t get_paste_offset (samplepos_t pos, unsigned paste_count, samplecnt_t duration) = 0;
virtual unsigned get_grid_beat_divisions(samplepos_t position) = 0;
virtual Temporal::Beats get_grid_type_as_beats (bool& success, samplepos_t position) = 0;
virtual Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) = 0;
virtual Temporal::timecnt_t get_paste_offset (Temporal::timepos_t const & pos, unsigned paste_count, Temporal::timecnt_t const & duration) = 0;
virtual unsigned get_grid_beat_divisions(Temporal::timepos_t const & position) = 0;
virtual Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
virtual int32_t get_grid_music_divisions (uint32_t event_state) = 0;
virtual void edit_notes (MidiRegionView*) = 0;
@ -496,7 +496,7 @@ public:
virtual ARDOUR::Location* find_location_from_marker (ArdourMarker*, bool&) const = 0;
virtual ArdourMarker* find_marker_from_location_id (PBD::ID const&, bool) const = 0;
virtual void snap_to_with_modifier (ARDOUR::MusicSample& first,
virtual void snap_to_with_modifier (Temporal::timepos_t & first,
GdkEvent const* ev,
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual) = 0;

View file

@ -153,7 +153,7 @@ QuantizeDialog::grid_size_to_musical_time (const string& txt) const
if ( txt == _grid_strings[0] ) { //"Main Grid"
bool success;
Temporal::Beats b = editor.get_grid_type_as_beats (success, 0);
Temporal::Beats b = editor.get_grid_type_as_beats (success, timepos_t (0));
if (!success) {
return 1.0;
}

View file

@ -286,27 +286,37 @@ RegionSelection::involves (const TimeAxisView& tv) const
return false;
}
samplepos_t
RegionSelection::start () const
timepos_t
RegionSelection::start_time () const
{
samplepos_t s = max_samplepos;
for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
s = min (s, (*i)->region()->position ());
if (empty()) {
return timepos_t ();
}
if (s == max_samplepos) {
return 0;
timepos_t s = timepos_t::max (front()->nt_position().time_domain());
for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
s = min (s, (*i)->region()->nt_position ());
}
if (s == timepos_t::max (front()->nt_position().time_domain())) {
return timepos_t ();
}
return s;
}
samplepos_t
RegionSelection::end_sample () const
timepos_t
RegionSelection::end_time () const
{
samplepos_t e = 0;
if (empty()) {
return timepos_t ();
}
timepos_t e (timepos_t::zero (front()->nt_position().time_domain()));
for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
e = max (e, (*i)->region()->last_sample ());
e = max (e, (*i)->region()->nt_end ());
}
return e;

View file

@ -57,11 +57,8 @@ public:
void clear_all();
samplepos_t start () const;
/* "end" collides with list<>::end */
samplepos_t end_sample () const;
Temporal::timepos_t start_time () const;
Temporal::timepos_t end_time () const;
const std::list<RegionView *>& by_layer() const { return _bylayer; }
void by_position (std::list<RegionView*>&) const;

View file

@ -1160,31 +1160,48 @@ RegionView::move_contents (sampleoffset_t distance)
region_changed (PropertyChange (ARDOUR::Properties::start));
}
/** Snap a sample offset within our region using the current snap settings.
* @param x Frame offset from this region's position.
/** Snap a time offset within our region using the current snap settings.
* @param x Time offset from this region's position.
* @param ensure_snap whether to ignore snap_mode (in the case of SnapOff) and magnetic snap.
* Used when inverting snap mode logic with key modifiers, or snap distance calculation.
* @return Snapped sample offset from this region's position.
* @return Snapped time offset from this region's position.
*/
MusicSample
RegionView::snap_sample_to_sample (sampleoffset_t x, bool ensure_snap) const
timepos_t
RegionView::snap_region_time_to_region_time (timepos_t const & x, bool ensure_snap) const
{
PublicEditor& editor = trackview.editor();
/* x is region relative, convert it to global absolute samples */
samplepos_t const session_sample = x + _region->position();
/* x is region relative, convert it to global absolute time */
timepos_t const session_sample = _region->position() + x;
/* try a snap in either direction */
MusicSample sample (session_sample, 0);
editor.snap_to (sample, RoundNearest, SnapToAny_Visual, ensure_snap);
timepos_t snapped = session_sample;
editor.snap_to (snapped, RoundNearest, false, ensure_snap);
/* if we went off the beginning of the region, snap forwards */
if (sample.sample < _region->position ()) {
sample.sample = session_sample;
editor.snap_to (sample, RoundUpAlways, SnapToAny_Visual, ensure_snap);
if (snapped < _region->position ()) {
snapped = session_sample;
editor.snap_to (snapped, RoundUpAlways, false, ensure_snap);
}
/* back to region relative, keeping the relevant divisor */
return MusicSample (sample.sample - _region->position(), sample.division);
/* back to region relative */
return _region->region_relative_position (snapped);
}
timecnt_t
RegionView::region_relative_distance (timecnt_t const & duration, Temporal::TimeDomain domain)
{
#warning NUTEMPO fixme needs new tempo map
//return _region->session().tempo_map().full_duration_at (_region->position(), duration, domain);
return timecnt_t();
}
timecnt_t
RegionView::source_relative_distance (timecnt_t const & duration, Temporal::TimeDomain domain)
{
#warning NUTEMPO fixme needs new tempo map
//return _region->session().tempo_map().full_duration_at (_region->source_position(), duration, domain);
return timecnt_t();
}
void

View file

@ -79,14 +79,14 @@ public:
virtual void set_height (double);
virtual void set_samples_per_pixel (double);
virtual bool set_duration (samplecnt_t, void*);
virtual bool set_duration (Temporal::timecnt_t const &, void*);
void move (double xdelta, double ydelta);
void raise_to_top ();
void lower_to_bottom ();
bool set_position(samplepos_t pos, void* src, double* delta = 0);
bool set_position(Temporal::timepos_t const & pos, void* src, double* delta = 0);
virtual void show_region_editor ();
void hide_region_editor ();
@ -125,11 +125,11 @@ public:
struct PositionOrder {
bool operator()(const RegionView* a, const RegionView* b) {
return a->region()->position() < b->region()->position();
return a->region()->nt_position() < b->region()->nt_position();
}
};
ARDOUR::MusicSample snap_sample_to_sample (ARDOUR::sampleoffset_t, bool ensure_snap = false) const;
Temporal::timepos_t snap_region_time_to_region_time (Temporal::timepos_t const &, bool ensure_snap = false) const;
void update_visibility ();
@ -172,6 +172,9 @@ protected:
void maybe_raise_cue_markers ();
Temporal::timecnt_t region_relative_distance (Temporal::timecnt_t const &, Temporal::TimeDomain desired_time_domain);
Temporal::timecnt_t source_relative_distance (Temporal::timecnt_t const &, Temporal::TimeDomain desired_time_domain);
boost::shared_ptr<ARDOUR::Region> _region;
ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position

View file

@ -241,14 +241,14 @@ RhythmFerret::run_analysis ()
for (RegionSelection::iterator i = regions_with_transients.begin(); i != regions_with_transients.end(); ++i) {
boost::shared_ptr<Readable> rd = boost::static_pointer_cast<AudioRegion> ((*i)->region());
boost::shared_ptr<AudioReadable> rd = boost::static_pointer_cast<AudioRegion> ((*i)->region());
switch (get_analysis_mode()) {
case PercussionOnset:
run_percussion_onset_analysis (rd, (*i)->region()->position(), current_results);
run_percussion_onset_analysis (rd, (*i)->region()->position_sample(), current_results);
break;
case NoteOnset:
run_note_onset_analysis (rd, (*i)->region()->position(), current_results);
run_note_onset_analysis (rd, (*i)->region()->position_sample(), current_results);
break;
default:
break;
@ -260,7 +260,7 @@ RhythmFerret::run_analysis ()
}
int
RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readable, sampleoffset_t /*offset*/, AnalysisFeatureList& results)
RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<AudioReadable> readable, sampleoffset_t /*offset*/, AnalysisFeatureList& results)
{
try {
TransientDetector t (_session->sample_rate());
@ -315,7 +315,7 @@ RhythmFerret::get_note_onset_function ()
}
int
RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, sampleoffset_t /*offset*/, AnalysisFeatureList& results)
RhythmFerret::run_note_onset_analysis (boost::shared_ptr<AudioReadable> readable, sampleoffset_t /*offset*/, AnalysisFeatureList& results)
{
try {
OnsetDetector t (_session->sample_rate());

View file

@ -36,7 +36,7 @@
#include "region_selection.h"
namespace ARDOUR {
class Readable;
class AudioReadable;
}
class Editor;
@ -117,8 +117,8 @@ private:
int get_note_onset_function ();
void run_analysis ();
int run_percussion_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, ARDOUR::sampleoffset_t offset, ARDOUR::AnalysisFeatureList& results);
int run_note_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, ARDOUR::sampleoffset_t offset, ARDOUR::AnalysisFeatureList& results);
int run_percussion_onset_analysis (boost::shared_ptr<ARDOUR::AudioReadable> region, ARDOUR::sampleoffset_t offset, ARDOUR::AnalysisFeatureList& results);
int run_note_onset_analysis (boost::shared_ptr<ARDOUR::AudioReadable> region, ARDOUR::sampleoffset_t offset, ARDOUR::AnalysisFeatureList& results);
void do_action ();
void do_split_action ();

View file

@ -1225,7 +1225,7 @@ RouteTimeAxisView::name_entry_changed (string const& str)
}
boost::shared_ptr<Region>
RouteTimeAxisView::find_next_region (samplepos_t pos, RegionPoint point, int32_t dir)
RouteTimeAxisView::find_next_region (timepos_t const & pos, RegionPoint point, int32_t dir)
{
boost::shared_ptr<Playlist> pl = playlist ();
@ -1236,8 +1236,8 @@ RouteTimeAxisView::find_next_region (samplepos_t pos, RegionPoint point, int32_t
return boost::shared_ptr<Region> ();
}
samplepos_t
RouteTimeAxisView::find_next_region_boundary (samplepos_t pos, int32_t dir)
timepos_t
RouteTimeAxisView::find_next_region_boundary (timepos_t const & pos, int32_t dir)
{
boost::shared_ptr<Playlist> pl = playlist ();
@ -1245,7 +1245,7 @@ RouteTimeAxisView::find_next_region_boundary (samplepos_t pos, int32_t dir)
return pl->find_next_region_boundary (pos, dir);
}
return -1;
return timepos_t::max (pos.time_domain());
}
void
@ -1299,7 +1299,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Delete:
if (playlist->cut (time) != 0) {
if (_editor.should_ripple()) {
playlist->ripple (time.start(), -time.length(), 0);
playlist->ripple (time.start_time(), -time.length(), NULL);
}
playlist->rdiff_and_add_command (_session);
}
@ -1309,7 +1309,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
if ((what_we_got = playlist->cut (time)) != 0) {
_editor.get_cut_buffer().add (what_we_got);
if (_editor.should_ripple()) {
playlist->ripple (time.start(), -time.length(), 0);
playlist->ripple (time.start_time(), -time.length(), NULL);
}
playlist->rdiff_and_add_command (_session);
}
@ -1323,7 +1323,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Clear:
if ((what_we_got = playlist->cut (time)) != 0) {
if (_editor.should_ripple()) {
playlist->ripple (time.start(), -time.length(), 0);
playlist->ripple (time.start_time(), -time.length(), NULL);
}
playlist->rdiff_and_add_command (_session);
what_we_got->release ();
@ -1333,7 +1333,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
}
bool
RouteTimeAxisView::paste (samplepos_t pos, const Selection& selection, PasteContext& ctx, const int32_t sub_num)
RouteTimeAxisView::paste (timepos_t const & pos, const Selection& selection, PasteContext& ctx)
{
if (!is_track()) {
return false;
@ -1351,18 +1351,20 @@ RouteTimeAxisView::paste (samplepos_t pos, const Selection& selection, PasteCont
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("paste to %1\n", pos));
/* add multi-paste offset if applicable */
std::pair<samplepos_t, samplepos_t> extent = (*p)->get_extent();
const samplecnt_t duration = extent.second - extent.first;
pos += _editor.get_paste_offset(pos, ctx.count, duration);
std::pair<timepos_t, timepos_t> extent = (*p)->get_extent();
const timecnt_t duration = extent.first.distance (extent.second);
timepos_t ppos = pos;
ppos += _editor.get_paste_offset (ppos, ctx.count, duration);
pl->clear_changes ();
pl->clear_owned_changes ();
if (_editor.should_ripple()) {
std::pair<samplepos_t, samplepos_t> extent = (*p)->get_extent_with_endspace();
samplecnt_t amount = extent.second - extent.first;
pl->ripple(pos, amount * ctx.times, boost::shared_ptr<Region>());
std::pair<timepos_t, timepos_t> extent = (*p)->get_extent_with_endspace();
timecnt_t amount = extent.first.distance (extent.second);
pl->ripple (ppos, amount * ctx.times, boost::shared_ptr<Region>());
}
pl->paste (*p, pos, ctx.times, sub_num);
pl->paste (*p, ppos, ctx.times);
vector<Command*> cmds;
pl->rdiff (cmds);

View file

@ -107,12 +107,12 @@ public:
void toggle_layer_display ();
LayerDisplay layer_display () const;
boost::shared_ptr<ARDOUR::Region> find_next_region (samplepos_t pos, ARDOUR::RegionPoint, int32_t dir);
samplepos_t find_next_region_boundary (samplepos_t pos, int32_t dir);
boost::shared_ptr<ARDOUR::Region> find_next_region (ARDOUR::timepos_t const & pos, ARDOUR::RegionPoint, int32_t dir);
ARDOUR::timepos_t find_next_region_boundary (ARDOUR::timepos_t const & pos, int32_t dir);
/* Editing operations */
void cut_copy_clear (Selection&, Editing::CutCopyOp);
bool paste (ARDOUR::samplepos_t, const Selection&, PasteContext& ctx, const int32_t sub_num);
bool paste (Temporal::timepos_t const &, const Selection&, PasteContext& ctx);
RegionView* combine_regions ();
void uncombine_regions ();
void uncombine_region (RegionView*);

View file

@ -533,7 +533,7 @@ RouteUI::mute_press (GdkEventButton* ev)
}
boost::shared_ptr<MuteControl> mc = _route->mute_control();
mc->start_touch (_session->audible_sample ());
mc->start_touch (timepos_t (_session->audible_sample ()));
_session->set_controls (route_list_to_control_list (rl, &Stripable::mute_control), _route->muted_by_self() ? 0.0 : 1.0, Controllable::InverseGroup);
}
@ -549,7 +549,7 @@ RouteUI::mute_press (GdkEventButton* ev)
}
boost::shared_ptr<MuteControl> mc = _route->mute_control();
mc->start_touch (_session->audible_sample ());
mc->start_touch (timepos_t (_session->audible_sample ()));
mc->set_value (!_route->muted_by_self(), Controllable::UseGroup);
}
}
@ -567,7 +567,7 @@ RouteUI::mute_release (GdkEventButton* /*ev*/)
_mute_release = 0;
}
_route->mute_control()->stop_touch (_session->audible_sample ());
_route->mute_control()->stop_touch (timepos_t (_session->audible_sample ()));
return false;
}

View file

@ -56,8 +56,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
struct AudioRangeComparator {
bool operator()(AudioRange a, AudioRange b) {
struct TimelineRangeComparator {
bool operator()(TimelineRange a, TimelineRange b) {
return a.start < b.start;
}
};
@ -306,11 +306,11 @@ Selection::toggle (samplepos_t start, samplepos_t end)
{
clear_objects(); // enforce object/range exclusivity
AudioRangeComparator cmp;
TimelineRangeComparator cmp;
/* XXX this implementation is incorrect */
time.push_back (AudioRange (start, end, ++next_time_id));
time.push_back (TimelineRange (start, end, ++next_time_id));
time.consolidate ();
time.sort (cmp);
@ -437,11 +437,11 @@ Selection::add (samplepos_t start, samplepos_t end)
{
clear_objects(); // enforce object/range exclusivity
AudioRangeComparator cmp;
TimelineRangeComparator cmp;
/* XXX this implementation is incorrect */
time.push_back (AudioRange (start, end, ++next_time_id));
time.push_back (TimelineRange (start, end, ++next_time_id));
time.consolidate ();
time.sort (cmp);
@ -457,7 +457,7 @@ Selection::move_time (samplecnt_t distance)
return;
}
for (list<AudioRange>::iterator i = time.begin(); i != time.end(); ++i) {
for (list<TimelineRange>::iterator i = time.begin(); i != time.end(); ++i) {
(*i).start += distance;
(*i).end += distance;
}
@ -470,15 +470,15 @@ Selection::replace (uint32_t sid, samplepos_t start, samplepos_t end)
{
clear_objects(); // enforce object/range exclusivity
for (list<AudioRange>::iterator i = time.begin(); i != time.end(); ++i) {
for (list<TimelineRange>::iterator i = time.begin(); i != time.end(); ++i) {
if ((*i).id == sid) {
time.erase (i);
time.push_back (AudioRange(start,end, sid));
time.push_back (TimelineRange(start,end, sid));
/* don't consolidate here */
AudioRangeComparator cmp;
TimelineRangeComparator cmp;
time.sort (cmp);
TimeChanged ();
@ -606,7 +606,7 @@ Selection::remove (uint32_t selection_id)
return;
}
for (list<AudioRange>::iterator i = time.begin(); i != time.end(); ++i) {
for (list<TimelineRange>::iterator i = time.begin(); i != time.end(); ++i) {
if ((*i).id == selection_id) {
time.erase (i);
@ -703,17 +703,17 @@ Selection::set (vector<RegionView*>& v)
* the list of tracks it applies to.
*/
long
Selection::set (samplepos_t start, samplepos_t end)
Selection::set (timepos_t const & start, timepos_t const & end)
{
clear_objects(); // enforce region/object exclusivity
clear_time();
if ((start == 0 && end == 0) || end < start) {
if ((start.zero() && end.zero()) || end < start) {
return 0;
}
if (time.empty()) {
time.push_back (AudioRange (start, end, ++next_time_id));
time.push_back (TimelineRange (start, end, ++next_time_id));
} else {
/* reuse the first entry, and remove all the rest */
@ -749,9 +749,9 @@ Selection::set_preserving_all_ranges (samplepos_t start, samplepos_t end)
}
if (time.empty ()) {
time.push_back (AudioRange (start, end, ++next_time_id));
time.push_back (TimelineRange (start, end, ++next_time_id));
} else {
time.sort (AudioRangeComparator ());
time.sort (TimelineRangeComparator ());
time.front().start = start;
time.back().end = end;
}
@ -1130,7 +1130,7 @@ Selection::get_state () const
}
for (TimeSelection::const_iterator i = time.begin(); i != time.end(); ++i) {
XMLNode* t = node->add_child (X_("AudioRange"));
XMLNode* t = node->add_child (X_("TimelineRange"));
t->set_property (X_("start"), (*i).start);
t->set_property (X_("end"), (*i).end);
}
@ -1297,7 +1297,7 @@ Selection::set_state (XMLNode const & node, int)
}
}
} else if ((*i)->name() == X_("AudioRange")) {
} else if ((*i)->name() == X_("TimelineRange")) {
samplepos_t start;
samplepos_t end;

View file

@ -136,7 +136,7 @@ public:
void set (const MidiNoteSelection&);
void set (RegionView*, bool also_clear_tracks = true);
void set (std::vector<RegionView*>&);
long set (samplepos_t, samplepos_t);
long set (Temporal::timepos_t const &, Temporal::timepos_t const &);
void set_preserving_all_ranges (samplepos_t, samplepos_t);
void set (boost::shared_ptr<Evoral::ControlList>);
void set (boost::shared_ptr<ARDOUR::Playlist>);

View file

@ -880,7 +880,7 @@ TimeAxisView::show_selection (TimeSelection& ts)
gap = ceil (gap * ui_scale);
}
for (list<AudioRange>::iterator i = ts.begin(); i != ts.end(); ++i) {
for (list<TimelineRange>::iterator i = ts.begin(); i != ts.end(); ++i) {
samplepos_t start, end;
samplecnt_t cnt;

View file

@ -190,10 +190,9 @@ public:
* @param ctx Paste context.
* @param sub_num music-time sub-division: \c -1: snap to bar, \c 1: exact beat, \c >1: \c (1 \c / \p sub_num \c ) beat-divisions
*/
virtual bool paste (ARDOUR::samplepos_t pos,
virtual bool paste (Temporal::timepos_t const & pos,
const Selection& selection,
PasteContext& ctx,
const int32_t sub_num)
PasteContext& ctx)
{
return false;
}
@ -204,7 +203,7 @@ public:
virtual void fade_range (TimeSelection&) {}
virtual boost::shared_ptr<ARDOUR::Region> find_next_region (samplepos_t /*pos*/, ARDOUR::RegionPoint, int32_t /*dir*/) {
virtual boost::shared_ptr<ARDOUR::Region> find_next_region (ARDOUR::timepos_t const & /*pos*/, ARDOUR::RegionPoint, int32_t /*dir*/) {
return boost::shared_ptr<ARDOUR::Region> ();
}

View file

@ -283,15 +283,15 @@ TimeAxisViewItem::canvas_group_event (GdkEvent* /*ev*/)
*/
bool
TimeAxisViewItem::set_position(samplepos_t pos, void* src, double* delta)
TimeAxisViewItem::set_position(timepos_t const & pos, void* src, double* delta)
{
if (position_locked) {
return false;
}
sample_position = pos;
sample_position = pos.samples();
double new_unit_pos = trackview.editor().sample_to_pixel (pos);
double new_unit_pos = trackview.editor().sample_to_pixel (sample_position);
if (delta) {
(*delta) = new_unit_pos - group->position().x;

View file

@ -54,14 +54,14 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
public:
virtual ~TimeAxisViewItem();
virtual bool set_position(samplepos_t, void*, double* delta = 0);
samplepos_t get_position() const;
virtual bool set_duration(samplecnt_t, void*);
samplecnt_t get_duration() const;
virtual void set_max_duration(samplecnt_t, void*);
samplecnt_t get_max_duration() const;
virtual void set_min_duration(samplecnt_t, void*);
samplecnt_t get_min_duration() const;
virtual bool set_position(Temporal::timepos_t const &, void*, double* delta = 0);
Temporal::timepos_t get_position() const;
virtual bool set_duration(Temporal::timecnt_t const &, void*);
Temporal::timecnt_t get_duration() const;
virtual void set_max_duration(Temporal::timecnt_t const &, void*);
Temporal::timecnt_t get_max_duration() const;
virtual void set_min_duration(Temporal::timecnt_t const &, void*);
Temporal::timecnt_t get_min_duration() const;
virtual void set_position_locked(bool, void*);
bool get_position_locked() const;
void set_max_duration_active(bool, void*);

View file

@ -234,16 +234,16 @@ TimeInfoBox::set_session (Session* s)
void
TimeInfoBox::region_selection_changed ()
{
samplepos_t s, e;
timepos_t s, e;
Selection& selection (Editor::instance().get_selection());
s = selection.regions.start();
e = selection.regions.end_sample();
s = selection.regions.start_time();
e = selection.regions.end_sample_time();
selection_start->set_off (false);
selection_end->set_off (false);
selection_length->set_off (false);
selection_start->set (s);
selection_end->set (e);
selection_length->set (e, false, s);
selection_start->set_time (s);
selection_end->set_time (e);
selection_length->set_duration (e, false, s);
}
void
@ -272,9 +272,10 @@ TimeInfoBox::selection_changed ()
selection_start->set_off (false);
selection_end->set_off (false);
selection_length->set_off (false);
selection_start->set (selection.time.start());
selection_end->set (selection.time.end_sample());
selection_length->set (selection.time.end_sample(), false, selection.time.start());
selection_start->set_time (selection.time.start_time());
selection_end->set_time (selection.time.end_time());
selection_length->set_is_duration (true, selection.time.start_time());
selection_length->set_duration (selection.time.start_time().distance (selection.time.end_time()));
} else {
selection_start->set_off (true);
selection_end->set_off (true);
@ -335,9 +336,10 @@ TimeInfoBox::selection_changed ()
selection_start->set_off (false);
selection_end->set_off (false);
selection_length->set_off (false);
selection_start->set (selection.time.start());
selection_end->set (selection.time.end_sample());
selection_length->set (selection.time.end_sample(), false, selection.time.start());
selection_start->set_time (selection.time.start_time());
selection_end->set_time (selection.time.end_time());
selection_length->set_is_duration (true, selection.time.start_time());
selection_length->set_duration (selection.time.start_time().distance (selection.time.end_time()));
}
break;
@ -382,6 +384,6 @@ TimeInfoBox::punch_changed (Location* loc)
punch_start->set_off (false);
punch_end->set_off (false);
punch_start->set (loc->start());
punch_end->set (loc->end());
punch_start->set_time (loc->start());
punch_end->set_time (loc->end());
}

View file

@ -1,22 +1,21 @@
/*
* Copyright (C) 2005-2017 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2009-2012 David Robillard <d@drobilla.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
Copyright (C) 2003-2004 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <algorithm>
@ -30,17 +29,17 @@
using namespace ARDOUR;
using namespace PBD;
AudioRange&
TimelineRange&
TimeSelection::operator[] (uint32_t which)
{
for (std::list<AudioRange>::iterator i = begin(); i != end(); ++i) {
for (std::list<TimelineRange>::iterator i = begin(); i != end(); ++i) {
if ((*i).id == which) {
return *i;
}
}
fatal << string_compose (_("programming error: request for non-existent audio range (%1)!"), which) << endmsg;
abort(); /*NOTREACHED*/
return *(new AudioRange(0,0,0)); /* keep the compiler happy; never called */
return *(new ARDOUR::TimelineRange(0,0,0)); /* keep the compiler happy; never called */
}
bool
@ -49,16 +48,16 @@ TimeSelection::consolidate ()
bool changed = false;
restart:
for (std::list<AudioRange>::iterator a = begin(); a != end(); ++a) {
for (std::list<AudioRange>::iterator b = begin(); b != end(); ++b) {
for (std::list<TimelineRange>::iterator a = begin(); a != end(); ++a) {
for (std::list<TimelineRange>::iterator b = begin(); b != end(); ++b) {
if (&(*a) == &(*b)) {
continue;
}
if (a->coverage (b->start, b->end) != Evoral::OverlapNone) {
a->start = std::min (a->start, b->start);
a->end = std::max (a->end, b->end);
if (a->coverage (b->start(), b->end()) != Temporal::OverlapNone) {
a->set_start (std::min (a->start(), b->start()));
a->set_end (std::max (a->end(), b->end()));
erase (b);
changed = true;
goto restart;
@ -70,43 +69,59 @@ TimeSelection::consolidate ()
}
samplepos_t
TimeSelection::start () const
TimeSelection::start_sample () const
{
if (empty()) {
return 0;
}
samplepos_t first = max_samplepos;
for (std::list<AudioRange>::const_iterator i = begin(); i != end(); ++i) {
if ((*i).start < first) {
first = (*i).start;
}
}
return first;
return start_time().sample ();
}
samplepos_t
TimeSelection::end_sample () const
{
samplepos_t last = 0;
/* XXX make this work like RegionSelection: no linear search needed */
for (std::list<AudioRange>::const_iterator i = begin(); i != end(); ++i) {
if ((*i).end > last) {
last = (*i).end;
}
}
return last;
return end_time().sample ();
}
samplecnt_t
TimeSelection::length() const
TimeSelection::length_samples() const
{
return length().samples();
}
timepos_t
TimeSelection::start_time () const
{
if (empty()) {
return 0;
}
return end_sample() - start() + 1;
timepos_t first = std::numeric_limits<timepos_t>::max();
for (std::list<TimelineRange>::const_iterator i = begin(); i != end(); ++i) {
if ((*i).start() < first) {
first = (*i).start();
}
}
return first;
}
timepos_t
TimeSelection::end_time() const
{
timepos_t last = std::numeric_limits<timepos_t>::min();
for (std::list<TimelineRange>::const_iterator i = begin(); i != end(); ++i) {
if ((*i).end() > last) {
last = (*i).end();
}
}
return last;
}
timecnt_t
TimeSelection::length() const
{
if (empty()) {
return timecnt_t();
}
return start_time().distance (end_time());
}

View file

@ -1,22 +1,21 @@
/*
* Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2009-2011 David Robillard <d@drobilla.net>
* Copyright (C) 2009 Carl Hetherington <carl@carlh.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
Copyright (C) 2000-2020 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_gtk_time_selection_h__
#define __ardour_gtk_time_selection_h__
@ -28,14 +27,18 @@ namespace ARDOUR {
class RouteGroup;
}
class TimeSelection : public std::list<ARDOUR::AudioRange>
class TimeSelection : public std::list<ARDOUR::TimelineRange>
{
public:
ARDOUR::AudioRange& operator[](uint32_t);
ARDOUR::TimelineRange & operator[](uint32_t);
ARDOUR::samplepos_t start() const;
ARDOUR::samplepos_t start_sample() const;
ARDOUR::samplepos_t end_sample() const;
ARDOUR::samplepos_t length() const;
ARDOUR::samplepos_t length_samples() const;
Temporal::timepos_t start_time() const;
Temporal::timepos_t end_time() const;
Temporal::timecnt_t length() const;
bool consolidate ();
};