Interpret start & length_beats properties as double rather than Evoral::Beats.

- Evoral::Beats operator!= would prevent an increment
	  of start_beats by intervals of less than a tick,
	  so its possible that other subtle problems
	  existed due to this kind of thing.
This commit is contained in:
nick_m 2016-10-10 03:39:57 +11:00
parent 631c8afc66
commit 4faf44588f
7 changed files with 42 additions and 44 deletions

View file

@ -5584,7 +5584,7 @@ NoteDrag::total_dx (const guint state) const
frameoffset_t const dx = _editor->pixel_to_sample (_drags->current_pointer_x() - grab_x()); frameoffset_t const dx = _editor->pixel_to_sample (_drags->current_pointer_x() - grab_x());
/* primary note time */ /* primary note time */
double const quarter_note_start = map.quarter_note_at_beat (_region->region()->beat() - _region->midi_region()->start_beats().to_double()); double const quarter_note_start = map.quarter_note_at_beat (_region->region()->beat() - _region->midi_region()->start_beats());
frameoffset_t const n = map.frame_at_quarter_note (quarter_note_start + _primary->note()->time().to_double()); frameoffset_t const n = map.frame_at_quarter_note (quarter_note_start + _primary->note()->time().to_double());
/* new time of the primary note in session frames */ /* new time of the primary note in session frames */

View file

@ -1673,8 +1673,8 @@ MidiRegionView::note_in_region_range (const boost::shared_ptr<NoteType> note, bo
const boost::shared_ptr<ARDOUR::MidiRegion> midi_reg = midi_region(); const boost::shared_ptr<ARDOUR::MidiRegion> midi_reg = midi_region();
/* must compare double explicitly as Beats::operator< rounds to ppqn */ /* must compare double explicitly as Beats::operator< rounds to ppqn */
const bool outside = (note->time().to_double() < midi_reg->start_beats().to_double() || const bool outside = (note->time().to_double() < midi_reg->start_beats() ||
note->time().to_double() > (midi_reg->start_beats() + midi_reg->length_beats()).to_double()); note->time().to_double() > midi_reg->start_beats() + midi_reg->length_beats());
visible = (note->note() >= midi_stream_view()->lowest_note()) && visible = (note->note() >= midi_stream_view()->lowest_note()) &&
(note->note() <= midi_stream_view()->highest_note()); (note->note() <= midi_stream_view()->highest_note());
@ -1704,7 +1704,7 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
TempoMap& map (trackview.session()->tempo_map()); TempoMap& map (trackview.session()->tempo_map());
const boost::shared_ptr<ARDOUR::MidiRegion> mr = midi_region(); const boost::shared_ptr<ARDOUR::MidiRegion> mr = midi_region();
boost::shared_ptr<NoteType> note = ev->note(); boost::shared_ptr<NoteType> note = ev->note();
const double qn_note_time = note->time().to_double() + ((_region->pulse() * 4.0) - mr->start_beats().to_double()); const double qn_note_time = note->time().to_double() + ((_region->pulse() * 4.0) - mr->start_beats());
const framepos_t note_start_frames = map.frame_at_quarter_note (qn_note_time) - _region->position(); const framepos_t note_start_frames = map.frame_at_quarter_note (qn_note_time) - _region->position();
const double x0 = trackview.editor().sample_to_pixel (note_start_frames); const double x0 = trackview.editor().sample_to_pixel (note_start_frames);
double x1; double x1;
@ -1713,13 +1713,13 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
/* trim note display to not overlap the end of its region */ /* trim note display to not overlap the end of its region */
if (note->length() > 0) { if (note->length() > 0) {
Evoral::Beats note_end_time = note->end_time(); double note_end_time = note->end_time().to_double();
if (note->end_time() > mr->start_beats() + mr->length_beats()) { if (note->end_time() > mr->start_beats() + mr->length_beats()) {
note_end_time = mr->start_beats() + mr->length_beats(); note_end_time = mr->start_beats() + mr->length_beats();
} }
const double session_qn_start = (_region->pulse() * 4.0) - mr->start_beats().to_double(); const double session_qn_start = (_region->pulse() * 4.0) - mr->start_beats();
const double quarter_note_end_time = session_qn_start + note_end_time.to_double(); const double quarter_note_end_time = session_qn_start + note_end_time;
const framepos_t note_end_frames = map.frame_at_quarter_note (quarter_note_end_time) - _region->position(); const framepos_t note_end_frames = map.frame_at_quarter_note (quarter_note_end_time) - _region->position();
x1 = std::max(1., trackview.editor().sample_to_pixel (note_end_frames)) - 1; x1 = std::max(1., trackview.editor().sample_to_pixel (note_end_frames)) - 1;
@ -1773,7 +1773,7 @@ MidiRegionView::update_hit (Hit* ev, bool update_ghost_regions)
{ {
boost::shared_ptr<NoteType> note = ev->note(); boost::shared_ptr<NoteType> note = ev->note();
const double note_time_qn = note->time().to_double() + ((_region->pulse() * 4.0) - midi_region()->start_beats().to_double()); const double note_time_qn = note->time().to_double() + ((_region->pulse() * 4.0) - midi_region()->start_beats());
const framepos_t note_start_frames = trackview.session()->tempo_map().frame_at_quarter_note (note_time_qn) - _region->position(); const framepos_t note_start_frames = trackview.session()->tempo_map().frame_at_quarter_note (note_time_qn) - _region->position();
const double x = trackview.editor().sample_to_pixel(note_start_frames); const double x = trackview.editor().sample_to_pixel(note_start_frames);
@ -2588,7 +2588,7 @@ MidiRegionView::note_dropped(NoteBase *, frameoffset_t dt, int8_t dnote)
for (Selection::iterator i = _selection.begin(); i != _selection.end() ; ++i) { for (Selection::iterator i = _selection.begin(); i != _selection.end() ; ++i) {
double const start_qn = (_region->pulse() * 4.0) - midi_region()->start_beats().to_double(); double const start_qn = (_region->pulse() * 4.0) - midi_region()->start_beats();
framepos_t new_frames = map.frame_at_quarter_note (start_qn + (*i)->note()->time().to_double()) + dt; framepos_t new_frames = map.frame_at_quarter_note (start_qn + (*i)->note()->time().to_double()) + dt;
Evoral::Beats new_time = Evoral::Beats (map.quarter_note_at_frame (new_frames) - start_qn); Evoral::Beats new_time = Evoral::Beats (map.quarter_note_at_frame (new_frames) - start_qn);
if (new_time < 0) { if (new_time < 0) {
@ -2915,7 +2915,7 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
/* and then to beats */ /* and then to beats */
const double e_baf = tmap.exact_beat_at_frame (current_fr + midi_region()->position(), divisions); const double e_baf = tmap.exact_beat_at_frame (current_fr + midi_region()->position(), divisions);
const double quarter_note_start_beat = tmap.quarter_note_at_beat (_region->beat() - midi_region()->start_beats().to_double()); const double quarter_note_start_beat = tmap.quarter_note_at_beat (_region->beat() - midi_region()->start_beats());
const Evoral::Beats x_beats = Evoral::Beats (tmap.quarter_note_at_beat (e_baf) - quarter_note_start_beat); const Evoral::Beats x_beats = Evoral::Beats (tmap.quarter_note_at_beat (e_baf) - quarter_note_start_beat);
if (at_front && x_beats < canvas_note->note()->end_time()) { if (at_front && x_beats < canvas_note->note()->end_time()) {
@ -4134,7 +4134,7 @@ MidiRegionView::snap_frame_to_grid_underneath (framepos_t p, int32_t divisions,
eqaf -= grid_beats.to_double(); eqaf -= grid_beats.to_double();
} }
} }
const double session_start_off = (_region->pulse() * 4.0) - midi_region()->start_beats().to_double(); const double session_start_off = (_region->pulse() * 4.0) - midi_region()->start_beats();
return Evoral::Beats (eqaf - session_start_off); return Evoral::Beats (eqaf - session_start_off);
} }

View file

@ -33,8 +33,8 @@ class XMLNode;
namespace ARDOUR { namespace ARDOUR {
namespace Properties { namespace Properties {
LIBARDOUR_API extern PBD::PropertyDescriptor<Evoral::Beats> start_beats; LIBARDOUR_API extern PBD::PropertyDescriptor<double> start_beats;
LIBARDOUR_API extern PBD::PropertyDescriptor<Evoral::Beats> length_beats; LIBARDOUR_API extern PBD::PropertyDescriptor<double> length_beats;
} }
} }
@ -106,8 +106,8 @@ class LIBARDOUR_API MidiRegion : public Region
boost::shared_ptr<const MidiModel> model() const; boost::shared_ptr<const MidiModel> model() const;
void fix_negative_start (); void fix_negative_start ();
Evoral::Beats start_beats () {return _start_beats.val(); } double start_beats () {return _start_beats; }
Evoral::Beats length_beats () {return _length_beats.val(); } double length_beats () {return _length_beats; }
void clobber_sources (boost::shared_ptr<MidiSource> source); void clobber_sources (boost::shared_ptr<MidiSource> source);
@ -119,8 +119,8 @@ class LIBARDOUR_API MidiRegion : public Region
private: private:
friend class RegionFactory; friend class RegionFactory;
PBD::Property<Evoral::Beats> _start_beats; PBD::Property<double> _start_beats;
PBD::Property<Evoral::Beats> _length_beats; PBD::Property<double> _length_beats;
MidiRegion (const SourceList&); MidiRegion (const SourceList&);
MidiRegion (boost::shared_ptr<const MidiRegion>); MidiRegion (boost::shared_ptr<const MidiRegion>);

View file

@ -1051,7 +1051,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
/* start of this region is the offset between the start of its capture and the start of the whole pass */ /* start of this region is the offset between the start of its capture and the start of the whole pass */
plist.add (Properties::start, (*ci)->start - initial_capture); plist.add (Properties::start, (*ci)->start - initial_capture);
plist.add (Properties::length, (*ci)->frames); plist.add (Properties::length, (*ci)->frames);
plist.add (Properties::length_beats, converter.from((*ci)->frames)); plist.add (Properties::length_beats, converter.from((*ci)->frames).to_double());
plist.add (Properties::name, region_name); plist.add (Properties::name, region_name);
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist)); boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));

View file

@ -53,8 +53,8 @@ using namespace PBD;
namespace ARDOUR { namespace ARDOUR {
namespace Properties { namespace Properties {
PBD::PropertyDescriptor<Evoral::Beats> start_beats; PBD::PropertyDescriptor<double> start_beats;
PBD::PropertyDescriptor<Evoral::Beats> length_beats; PBD::PropertyDescriptor<double> length_beats;
} }
} }
@ -77,8 +77,8 @@ MidiRegion::register_properties ()
/* Basic MidiRegion constructor (many channels) */ /* Basic MidiRegion constructor (many channels) */
MidiRegion::MidiRegion (const SourceList& srcs) MidiRegion::MidiRegion (const SourceList& srcs)
: Region (srcs) : Region (srcs)
, _start_beats (Properties::start_beats, Evoral::Beats()) , _start_beats (Properties::start_beats, 0.0)
, _length_beats (Properties::length_beats, midi_source(0)->length_beats()) , _length_beats (Properties::length_beats, midi_source(0)->length_beats().to_double())
{ {
register_properties (); register_properties ();
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this)); midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
@ -103,10 +103,10 @@ MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other)
/** Create a new MidiRegion that is part of an existing one */ /** Create a new MidiRegion that is part of an existing one */
MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, frameoffset_t offset, const int32_t sub_num) MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, frameoffset_t offset, const int32_t sub_num)
: Region (other, offset, sub_num) : Region (other, offset, sub_num)
, _start_beats (Properties::start_beats, Evoral::Beats()) , _start_beats (Properties::start_beats, 0.0)
, _length_beats (Properties::length_beats, other->_length_beats) , _length_beats (Properties::length_beats, other->_length_beats)
{ {
_start_beats = Evoral::Beats (_session.tempo_map().exact_qn_at_frame (other->_position + offset, sub_num) - (other->pulse() * 4.0)) + other->_start_beats; _start_beats = (_session.tempo_map().exact_qn_at_frame (other->_position + offset, sub_num) - (other->pulse() * 4.0)) + other->_start_beats;
update_length_beats (sub_num); update_length_beats (sub_num);
register_properties (); register_properties ();
@ -223,7 +223,7 @@ MidiRegion::post_set (const PropertyChange& pc)
void void
MidiRegion::set_start_beats_from_start_frames () MidiRegion::set_start_beats_from_start_frames ()
{ {
_start_beats = Evoral::Beats ((pulse() * 4.0) - _session.tempo_map().quarter_note_at_frame (_position - _start)); _start_beats = (pulse() * 4.0) - _session.tempo_map().quarter_note_at_frame (_position - _start);
} }
void void
@ -265,10 +265,10 @@ MidiRegion::update_after_tempo_map_change (bool /* send */)
For now, the musical position at the region start is retained, but subsequent events For now, the musical position at the region start is retained, but subsequent events
will maintain their beat distance according to the map. will maintain their beat distance according to the map.
*/ */
_start = _position - _session.tempo_map().frame_at_pulse (pulse() - (_start_beats.val().to_double() / 4.0)); _start = _position - _session.tempo_map().frame_at_pulse (pulse() - (_start_beats / 4.0));
/* _length doesn't change for audio-locked regions. update length_beats to match. */ /* _length doesn't change for audio-locked regions. update length_beats to match. */
_length_beats = Evoral::Beats (_session.tempo_map().quarter_note_at_frame (_position + _length) - _session.tempo_map().quarter_note_at_frame (_position)); _length_beats = _session.tempo_map().quarter_note_at_frame (_position + _length) - _session.tempo_map().quarter_note_at_frame (_position);
s_and_l.add (Properties::start); s_and_l.add (Properties::start);
s_and_l.add (Properties::length_beats); s_and_l.add (Properties::length_beats);
@ -280,7 +280,7 @@ MidiRegion::update_after_tempo_map_change (bool /* send */)
Region::update_after_tempo_map_change (false); Region::update_after_tempo_map_change (false);
/* _start has now been updated. */ /* _start has now been updated. */
_length = _session.tempo_map().frame_at_pulse (pulse() + (_length_beats.val().to_double() / 4.0)) - _position; _length = _session.tempo_map().frame_at_pulse (pulse() + (_length_beats / 4.0)) - _position;
if (old_start != _start) { if (old_start != _start) {
s_and_l.add (Properties::start); s_and_l.add (Properties::start);
@ -298,7 +298,7 @@ MidiRegion::update_after_tempo_map_change (bool /* send */)
void void
MidiRegion::update_length_beats (const int32_t sub_num) MidiRegion::update_length_beats (const int32_t sub_num)
{ {
_length_beats = Evoral::Beats (_session.tempo_map().exact_qn_at_frame (_position + _length, sub_num) - (pulse() * 4.0)); _length_beats = _session.tempo_map().exact_qn_at_frame (_position + _length, sub_num) - (pulse() * 4.0);
} }
void void
@ -312,20 +312,20 @@ MidiRegion::set_position_internal (framepos_t pos, bool allow_bbt_recompute, con
} }
/* set _start to new position in tempo map */ /* set _start to new position in tempo map */
_start = _position - _session.tempo_map().frame_at_pulse (pulse() - (_start_beats.val().to_double() / 4.0)); _start = _position - _session.tempo_map().frame_at_pulse (pulse() - (_start_beats / 4.0));
/* in construction from src */ /* in construction from src */
if (_length_beats == Evoral::Beats()) { if (_length_beats == 0.0) {
update_length_beats (sub_num); update_length_beats (sub_num);
} }
if (position_lock_style() == AudioTime) { if (position_lock_style() == AudioTime) {
_length_beats = Evoral::Beats (_session.tempo_map().quarter_note_at_frame (_position + _length) - _session.tempo_map().quarter_note_at_frame (_position)); _length_beats = _session.tempo_map().quarter_note_at_frame (_position + _length) - _session.tempo_map().quarter_note_at_frame (_position);
} else { } else {
/* leave _length_beats alone, and change _length to reflect the state of things /* leave _length_beats alone, and change _length to reflect the state of things
at the new position (tempo map may dictate a different number of frames). at the new position (tempo map may dictate a different number of frames).
*/ */
Region::set_length_internal (_session.tempo_map().frame_at_pulse (pulse() + (_length_beats.val().to_double() / 4.0)) - _position, sub_num); Region::set_length_internal (_session.tempo_map().frame_at_pulse (pulse() + (_length_beats / 4.0)) - _position, sub_num);
} }
} }
@ -425,7 +425,7 @@ MidiRegion::_read_at (const SourceList& /*srcs*/,
filter, filter,
_filtered_parameters, _filtered_parameters,
pulse(), pulse(),
_start_beats.val().to_double() _start_beats
) != to_read) { ) != to_read) {
return 0; /* "read nothing" */ return 0; /* "read nothing" */
} }
@ -591,7 +591,7 @@ MidiRegion::fix_negative_start ()
model()->insert_silence_at_start (c.from (-_start)); model()->insert_silence_at_start (c.from (-_start));
_start = 0; _start = 0;
_start_beats = Evoral::Beats(); _start_beats = 0.0;
} }
void void
@ -630,16 +630,14 @@ MidiRegion::trim_to_internal (framepos_t position, framecnt_t length, const int3
set_position_internal (position, true, sub_num); set_position_internal (position, true, sub_num);
what_changed.add (Properties::position); what_changed.add (Properties::position);
double new_start_qn = start_beats().to_double() + (pos_qn - old_pos_qn); double new_start_qn = start_beats() + (pos_qn - old_pos_qn);
const framepos_t new_start = _position - _session.tempo_map().frame_at_quarter_note (pos_qn - new_start_qn); const framepos_t new_start = _position - _session.tempo_map().frame_at_quarter_note (pos_qn - new_start_qn);
if (!verify_start_and_length (new_start, length)) { if (!verify_start_and_length (new_start, length)) {
return; return;
} }
/* at small deltas, (high zooms) the property will not change without this (tick resolution of Beats::operator!=)*/ _start_beats = new_start_qn;
_start_beats += Evoral::Beats (new_start_qn) + start_beats().tick() * 2.0;
_start_beats = Evoral::Beats (new_start_qn);
what_changed.add (Properties::start_beats); what_changed.add (Properties::start_beats);
set_start_internal (new_start, sub_num); set_start_internal (new_start, sub_num);

View file

@ -17,7 +17,7 @@ function factory () return function ()
assert (ar and mr) assert (ar and mr)
local a_off = ar:position () local a_off = ar:position ()
local b_off = 4.0 * mr:pulse () - mr:start_beats ():to_double () local b_off = 4.0 * mr:pulse () - mr:start_beats ()
vamp:analyze (ar:to_readable (), 0, nil) vamp:analyze (ar:to_readable (), 0, nil)
local fl = vamp:plugin ():getRemainingFeatures ():at (0) local fl = vamp:plugin ():getRemainingFeatures ():at (0)

View file

@ -135,7 +135,7 @@ ensure_per_region_source (Session* session, boost::shared_ptr<MidiRegion> region
Source::Lock newsrc_lock (newsrc->mutex()); Source::Lock newsrc_lock (newsrc->mutex());
write_bbt_source_to_source (region->midi_source(0), newsrc, newsrc_lock, region->pulse() - (region->start_beats().to_double() / 4.0)); write_bbt_source_to_source (region->midi_source(0), newsrc, newsrc_lock, region->pulse() - (region->start_beats() / 4.0));
cout << UTILNAME << ":" << endl cout << UTILNAME << ":" << endl
<< " Created new midi source file" << endl << " Created new midi source file" << endl
@ -189,7 +189,7 @@ ensure_per_source_source (Session* session, boost::shared_ptr<MidiRegion> region
Source::Lock newsrc_lock (newsrc->mutex()); Source::Lock newsrc_lock (newsrc->mutex());
write_bbt_source_to_source (region->midi_source(0), newsrc, newsrc_lock, region->pulse() - (region->start_beats().to_double() / 4.0)); write_bbt_source_to_source (region->midi_source(0), newsrc, newsrc_lock, region->pulse() - (region->start_beats() / 4.0));
cout << UTILNAME << ":" << endl cout << UTILNAME << ":" << endl
<< " Created new midi source file" << endl << " Created new midi source file" << endl
@ -206,7 +206,7 @@ reset_start (Session* session, boost::shared_ptr<MidiRegion> region)
{ {
/* set start_beats to quarter note value from incorrect bbt*/ /* set start_beats to quarter note value from incorrect bbt*/
TempoMap& tmap (session->tempo_map()); TempoMap& tmap (session->tempo_map());
double new_start_qn = (tmap.pulse_at_beat (region->beat()) - tmap.pulse_at_beat (region->beat() - region->start_beats().to_double())) * 4.0; double new_start_qn = (tmap.pulse_at_beat (region->beat()) - tmap.pulse_at_beat (region->beat() - region->start_beats())) * 4.0;
/* force a change to start and start_beats */ /* force a change to start and start_beats */
PositionLockStyle old_pls = region->position_lock_style(); PositionLockStyle old_pls = region->position_lock_style();
@ -222,7 +222,7 @@ reset_length (Session* session, boost::shared_ptr<MidiRegion> region)
{ {
/* set length_beats to quarter note value */ /* set length_beats to quarter note value */
TempoMap& tmap (session->tempo_map()); TempoMap& tmap (session->tempo_map());
double new_length_qn = (tmap.pulse_at_beat (region->beat() + region->length_beats().to_double()) double new_length_qn = (tmap.pulse_at_beat (region->beat() + region->length_beats())
- tmap.pulse_at_beat (region->beat())) * 4.0; - tmap.pulse_at_beat (region->beat())) * 4.0;
/* force a change to length and length_beats */ /* force a change to length and length_beats */