- boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(r);
- if (!region)
- return -1;
-
- // FIXME: how to make a whole file region if it isn't?
- //assert(region->whole_file());
-
- boost::shared_ptr<MidiSource> src = region->midi_source(0);
- src->load_model();
-
- boost::shared_ptr<MidiModel> model = src->model();
-
- // FIXME: Model really needs to be switched to beat time (double) ASAP
-
- const Tempo& t = session.tempo_map().tempo_at(r->start());
- const Meter& m = session.tempo_map().meter_at(r->start());
-
- double q_frames = _q * (m.frames_per_bar(t, session.frame_rate()) / (double)m.beats_per_bar());
-
- for (MidiModel::Notes::iterator i = model->notes().begin(); i != model->notes().end(); ++i) {
- const double new_time = lrint(i->time() / q_frames) * q_frames;
- const double new_dur = ((i->time() != 0 && new_dur < (q_frames * 1.5))
- ? q_frames
- : lrint(i->duration() / q_frames) * q_frames);
-
- i->set_time(new_time);
- i->set_duration(new_dur);
+ /* beats start out numbered at zero.
+ *
+ * every other position on the start-quantize-grid is
+ * optionally swung, meaning that its position is moved
+ * somewhere between its natural position and 2/3 of
+ * the way to the next start-quantize-grid position.
+ *
+ * so, if the _start grid is 0.5, the beat at 0 isn't
+ * swung, but something at 0.5 is, the beat at 1 isn't
+ * swung, but something at 1.5 is.
+ *
+ * if the start grid is 1.0, the beat at 0 isn't swung,
+ * but the beat at 1.0 is. the beat at 2.0 isn't swung,
+ * but the beat at 3.0 is. and so on.
+ *
+ * so the criterion for a position being swung is
+ * whether or not ((possible_grid_position / grid) % 2) != 0
+ */
+
+ const bool swing_quantize_grid_position = pos > 0.0 && fmod ((pos/grid), 2.0) != 0;
+ const bool swing_previous_grid_position = pos > grid && fmod ((pos-grid)/grid, 2.0) != 0;
+
+ /* one of these will not be subject to swing */
+
+ double swung_pos = pos;
+ double swung_previous_grid_position;
+
+ if (pos > grid) {
+ swung_previous_grid_position = pos - grid;
+ } else {
+ swung_previous_grid_position = 0.0;