Tempo ramps - midi notes resize when dragged, misc bug fixes.
This commit is contained in:
parent
8fce08610a
commit
d3c24fe0ca
@ -1703,22 +1703,26 @@ void
|
||||
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) {
|
||||
@ -1726,7 +1730,7 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
|
||||
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;
|
||||
@ -2508,6 +2512,8 @@ MidiRegionView::move_selection(double dx, double dy, double cumulative_dy)
|
||||
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()) {
|
||||
|
@ -435,8 +435,9 @@ private:
|
||||
double beat_at_frame_locked (const Metrics& metrics, framecnt_t frame) const;
|
||||
framecnt_t frame_at_beat_locked (const Metrics& metrics, double beat) const;
|
||||
double tick_at_frame_locked (const Metrics& metrics, framecnt_t frame) const;
|
||||
|
||||
double tick_offset_at (const Metrics& metrics, double tick) const;
|
||||
framecnt_t frame_offset_at (const Metrics& metrics, framepos_t frame) const;
|
||||
frameoffset_t frame_offset_at (const Metrics& metrics, framepos_t frame) const;
|
||||
|
||||
framecnt_t frame_at_tick_locked (const Metrics& metrics, double tick) const;
|
||||
framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&);
|
||||
|
@ -1529,7 +1529,9 @@ TempoMap::bbt_to_beats_locked (const Metrics& metrics, Timecode::BBT_Time bbt)
|
||||
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) {
|
||||
@ -1651,6 +1653,35 @@ TempoMap::tick_at_frame_locked (const Metrics& metrics, framecnt_t frame) const
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
@ -1675,10 +1706,10 @@ 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;
|
||||
@ -1687,7 +1718,7 @@ TempoMap::frame_offset_at (const Metrics& metrics, framepos_t frame) const
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1695,36 +1726,6 @@ TempoMap::frame_offset_at (const Metrics& metrics, framepos_t frame) const
|
||||
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
|
||||
{
|
||||
@ -1943,7 +1944,6 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
|
||||
}
|
||||
|
||||
imaginary.sort (cmp);
|
||||
|
||||
if (section->position_lock_style() == AudioTime) {
|
||||
/* we're setting the beat */
|
||||
section->set_position_lock_style (MusicTime);
|
||||
@ -2094,9 +2094,11 @@ TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
|
||||
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
|
||||
@ -2272,11 +2274,12 @@ TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
|
||||
|
||||
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));
|
||||
@ -2348,7 +2351,7 @@ const Tempo
|
||||
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;
|
||||
@ -2356,9 +2359,9 @@ TempoMap::tempo_at (framepos_t frame) const
|
||||
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;
|
||||
}
|
||||
@ -2376,7 +2379,7 @@ const MeterSection&
|
||||
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;
|
||||
|
||||
@ -2385,7 +2388,7 @@ TempoMap::meter_section_at (framepos_t frame) const
|
||||
|
||||
if ((t = dynamic_cast<MeterSection*> (*i)) != 0) {
|
||||
|
||||
if ((*i)->frame() > frame) {
|
||||
if ((*i)->frame() > frame_off) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2433,7 +2436,9 @@ TempoMap::meter_section_at (double beat) const
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user