Tempo ramps - midi notes resize when dragged, misc bug fixes.
authornick_m <mainsbridge@gmail.com>
Sun, 13 Mar 2016 17:09:53 +0000 (04:09 +1100)
committernick_m <mainsbridge@gmail.com>
Fri, 27 May 2016 13:38:11 +0000 (23:38 +1000)
gtk2_ardour/midi_region_view.cc
libs/ardour/ardour/tempo.h
libs/ardour/tempo.cc

index e3ff928e1d0a527f19eb77497208c697eed20656..f31735fcd2c09655454479db6634fe3be4973846 100644 (file)
@@ -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()) {
index 10cf44e06c48232de75eb5c3a4ccab0908edb615..a73379b62fc06fa744f267634e164a3dc1098ca9 100644 (file)
@@ -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&);
index 66a10e4483d35ab345be40936787f27d66b34f8c..7c4ffd6a104186c6c1ee7a03ef13a11f65294969 100644 (file)
@@ -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();
 }