MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
{
boost::shared_ptr<NoteType> note = ev->note();
- const double x = trackview.editor().sample_to_pixel (source_beats_to_region_frames (note->time()));
+ const double x0 = trackview.editor().sample_to_pixel (source_beats_to_region_frames (note->time()));
+ double x1;
const double y0 = 1 + floor(midi_stream_view()->note_to_y(note->note()));
-
- ev->set_x0 (x);
- ev->set_y0 (y0);
+ double y1;
/* trim note display to not overlap the end of its region */
if (note->length() > 0) {
const framepos_t note_end_frames = min (source_beats_to_region_frames (note->end_time()), _region->length());
- ev->set_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;
} else {
- ev->set_x1 (std::max(1., trackview.editor().sample_to_pixel (_region->length())) - 1);
+ x1 = std::max(1., trackview.editor().sample_to_pixel (_region->length())) - 1;
}
- ev->set_y1 (y0 + std::max(1., floor(midi_stream_view()->note_height()) - 1));
+ y1 = y0 + std::max(1., floor(midi_stream_view()->note_height()) - 1);
+
+ ev->set_x0 (x0);
+ ev->set_x1 (x1);
+ ev->set_y0 (y0);
+ ev->set_y1 (y1);
if (!note->length()) {
if (_active_notes && note->note() < 128) {
if (old_rect) {
/* There is an active note on this key, so we have a stuck
note. Finish the old rectangle here. */
- old_rect->set_x1 (x);
+ old_rect->set_x1 (x1);
old_rect->set_outline_all ();
}
_active_notes[note->note()] = ev;
to_play.push_back ((*i)->note());
}
(*i)->move_event(dx, dy);
+ Note* canvas_note = dynamic_cast<Note*>(*i);
+ canvas_note->set_x1 (snap_to_pixel (canvas_note->x1(), false));
}
if (dy && !_selection.empty() && !_no_sound_notes && UIConfiguration::instance().get_sound_midi_notes()) {
double accumulated_beats = 0.0;
double accumulated_bars = 0.0;
MeterSection* prev_ms = 0;
-
+ /* because audio-locked meters have 'fake' integral beats,
+ we don't have to worry about any offset here.
+ */
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
MeterSection* m;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
}
+framecnt_t
+TempoMap::frame_at_tick_locked (const Metrics& metrics, double tick) const
+{
+ /* HOLD THE READER LOCK */
+
+ const TempoSection* prev_ts = 0;
+ double accumulated_ticks = 0.0;
+
+ for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+ TempoSection* t;
+
+ if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+ if (prev_ts && t->tick() > tick) {
+ return prev_ts->frame_at_tick (tick, _frame_rate);
+ }
+
+ accumulated_ticks = t->tick();
+ prev_ts = t;
+ }
+ }
+ /* must be treated as constant, irrespective of _type */
+ double const ticks_in_section = tick - accumulated_ticks;
+ double const dtime = (ticks_in_section / BBT_Time::ticks_per_beat) * prev_ts->frames_per_beat (_frame_rate);
+
+ framecnt_t const ret = (((framecnt_t) floor (dtime)) + prev_ts->frame());
+
+ return ret;
+}
+
double
TempoMap::tick_offset_at (const Metrics& metrics, double tick) const
{
return beat_off;
}
-framecnt_t
+frameoffset_t
TempoMap::frame_offset_at (const Metrics& metrics, framepos_t frame) const
{
- framecnt_t frame_off = 0;
+ frameoffset_t frame_off = 0;
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
MeterSection* m = 0;
break;
}
if (m->position_lock_style() == AudioTime) {
- frame_off = frame_at_beat_locked (metrics, m->beat()) - m->frame();
+ frame_off += frame_at_beat_locked (metrics, m->beat()) - m->frame();
}
}
}
return frame_off;
}
-framecnt_t
-TempoMap::frame_at_tick_locked (const Metrics& metrics, double tick) const
-{
- /* HOLD THE READER LOCK */
-
- const TempoSection* prev_ts = 0;
- double accumulated_ticks = 0.0;
-
- for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
- TempoSection* t;
-
- if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
- if (prev_ts && t->tick() > tick) {
- /* prev_ts is the one affecting us. */
- return prev_ts->frame_at_tick (tick, _frame_rate);
- }
-
- accumulated_ticks = t->tick();
- prev_ts = t;
- }
- }
- /* must be treated as constant, irrespective of _type */
- double const ticks_in_section = tick - accumulated_ticks;
- double const dtime = (ticks_in_section / BBT_Time::ticks_per_beat) * prev_ts->frames_per_beat (_frame_rate);
-
- framecnt_t const ret = (((framecnt_t) floor (dtime)) + prev_ts->frame());
-
- return ret;
-}
-
double
TempoMap::beat_at_frame (framecnt_t frame) const
{
}
imaginary.sort (cmp);
-
if (section->position_lock_style() == AudioTime) {
/* we're setting the beat */
section->set_position_lock_style (MusicTime);
framecnt_t const ret = time_at_bbt - offset_pos;
return ret - frame_offset_at (_metrics, pos);
}
+
double const ticks = bbt.ticks + (bbt.beats * BBT_Time::ticks_per_beat);
framecnt_t const ret = (framecnt_t) floor ((ticks / BBT_Time::ticks_per_beat) * first->frames_per_beat(_frame_rate));
- return ret - frame_offset_at (_metrics, pos);
+ /* daft */
+ return (offset_pos + ret) - frame_offset_at (_metrics, pos);
}
framepos_t
while (cnt <= upper_beat) {
framecnt_t pos = frame_at_beat_locked (_metrics, cnt);
- framecnt_t const frame_offset = frame_offset_at (_metrics, pos);
+ Tempo const tempo = tempo_at (pos);
+
+ frameoffset_t const frame_offset = frame_offset_at (_metrics, pos);
pos -= frame_offset;
MeterSection const meter = meter_section_at (pos);
- Tempo const tempo = tempo_at (pos);
BBT_Time const bbt = beats_to_bbt_locked (_metrics, (double) cnt);
points.push_back (BBTPoint (meter, tempo, pos, bbt.bars, bbt.beats));
TempoMap::tempo_at (framepos_t frame) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
-
+ frameoffset_t const frame_off = frame + frame_offset_at (_metrics, frame);
TempoSection* prev_ts = 0;
Metrics::const_iterator i;
for (i = _metrics.begin(); i != _metrics.end(); ++i) {
TempoSection* t;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
- if ((prev_ts) && t->frame() > frame) {
+ if ((prev_ts) && t->frame() > frame_off) {
/* this is the one past frame */
- double const ret = prev_ts->tempo_at_frame (frame, _frame_rate);
+ double const ret = prev_ts->tempo_at_frame (frame_off, _frame_rate);
Tempo const ret_tempo (ret, prev_ts->note_type());
return ret_tempo;
}
TempoMap::meter_section_at (framepos_t frame) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
-
+ framepos_t const frame_off = frame + frame_offset_at (_metrics, frame);
Metrics::const_iterator i;
MeterSection* prev = 0;
if ((t = dynamic_cast<MeterSection*> (*i)) != 0) {
- if ((*i)->frame() > frame) {
+ if ((*i)->frame() > frame_off) {
break;
}
const Meter&
TempoMap::meter_at (framepos_t frame) const
{
- TempoMetric m (metric_at (frame));
+ framepos_t const frame_off = frame + frame_offset_at (_metrics, frame);
+ TempoMetric m (metric_at (frame_off));
+
return m.meter();
}