Compare commits
2 Commits
1b6e4b0b84
...
a258b82ce9
Author | SHA1 | Date |
---|---|---|
Ben Loftis | a258b82ce9 | |
Ben Loftis | 912f9e5ea3 |
|
@ -2547,8 +2547,7 @@ private:
|
|||
friend class RegionMoveDrag;
|
||||
friend class TrimDrag;
|
||||
friend class MappingTwistDrag;
|
||||
friend class MappingLinearDrag;
|
||||
friend class MappingStretchDrag;
|
||||
friend class MappingEndDrag;
|
||||
friend class MeterMarkerDrag;
|
||||
friend class BBTMarkerDrag;
|
||||
friend class TempoMarkerDrag;
|
||||
|
|
|
@ -3476,7 +3476,7 @@ BBTMarkerDrag::aborted (bool moved)
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
MappingLinearDrag::MappingLinearDrag (Editor* e, ArdourCanvas::Item* i, Temporal::TempoMap::WritableSharedPtr& wmap, TempoPoint& tp, TempoPoint& ap, XMLNode& before)
|
||||
MappingEndDrag::MappingEndDrag (Editor* e, ArdourCanvas::Item* i, Temporal::TempoMap::WritableSharedPtr& wmap, TempoPoint& tp, TempoPoint& ap, XMLNode& before)
|
||||
: Drag (e, i, Temporal::BeatTime)
|
||||
, _tempo (tp)
|
||||
, _after (ap)
|
||||
|
@ -3485,12 +3485,12 @@ MappingLinearDrag::MappingLinearDrag (Editor* e, ArdourCanvas::Item* i, Temporal
|
|||
, _before_state (&before)
|
||||
, _drag_valid (true)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::Drags, "New MappingLinearDrag\n");
|
||||
DEBUG_TRACE (DEBUG::Drags, "New MappingEndDrag\n");
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MappingLinearDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||
MappingEndDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||
{
|
||||
Drag::start_grab (event, cursor);
|
||||
|
||||
|
@ -3509,7 +3509,7 @@ MappingLinearDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||
}
|
||||
|
||||
void
|
||||
MappingLinearDrag::setup_pointer_offset ()
|
||||
MappingEndDrag::setup_pointer_offset ()
|
||||
{
|
||||
Beats grab_qn = max (Beats(), raw_grab_time().beats());
|
||||
|
||||
|
@ -3524,7 +3524,7 @@ MappingLinearDrag::setup_pointer_offset ()
|
|||
}
|
||||
|
||||
void
|
||||
MappingLinearDrag::motion (GdkEvent* event, bool first_move)
|
||||
MappingEndDrag::motion (GdkEvent* event, bool first_move)
|
||||
{
|
||||
if (!_drag_valid) {
|
||||
return;
|
||||
|
@ -3554,7 +3554,7 @@ MappingLinearDrag::motion (GdkEvent* event, bool first_move)
|
|||
}
|
||||
|
||||
void
|
||||
MappingLinearDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
MappingEndDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
{
|
||||
if (!_drag_valid) {
|
||||
aborted (false);
|
||||
|
@ -3576,7 +3576,7 @@ MappingLinearDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||
}
|
||||
|
||||
void
|
||||
MappingLinearDrag::aborted (bool /* moved */)
|
||||
MappingEndDrag::aborted (bool /* moved */)
|
||||
{
|
||||
_editor->abort_reversible_command ();
|
||||
_editor->abort_tempo_mapping ();
|
||||
|
@ -3600,7 +3600,8 @@ MappingTwistDrag::MappingTwistDrag (Editor* e, ArdourCanvas::Item* i, Temporal::
|
|||
, _drag_valid (true)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::Drags, "New MappingTwistDrag\n");
|
||||
initial_npm = focus.note_types_per_minute ();
|
||||
initial_focus_npm = focus.note_types_per_minute ();
|
||||
initial_pre_npm = prv.note_types_per_minute ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3630,13 +3631,15 @@ MappingTwistDrag::motion (GdkEvent* event, bool first_move)
|
|||
if (_drags->current_pointer_x() < last_pointer_x()) {
|
||||
if (direction < 0.) {
|
||||
direction = 1.;
|
||||
initial_npm += delta;
|
||||
initial_focus_npm += delta;
|
||||
initial_pre_npm += delta;
|
||||
delta = 0.;
|
||||
}
|
||||
} else {
|
||||
if (direction >= 0.) {
|
||||
direction = -1.;
|
||||
initial_npm += delta;
|
||||
initial_focus_npm += delta;
|
||||
initial_pre_npm += delta;
|
||||
delta = 0.;
|
||||
}
|
||||
}
|
||||
|
@ -3657,7 +3660,12 @@ MappingTwistDrag::motion (GdkEvent* event, bool first_move)
|
|||
delta += scaling_factor * pixel_distance;
|
||||
std::cerr << "pixels " << pixel_distance << " spp " << spp << " SF " << scaling_factor << " delta = " << delta << std::endl;
|
||||
|
||||
map->twist_tempi (prev, focus, next, initial_npm + delta);
|
||||
bool do_a_ramp = true; // @ben
|
||||
if (do_a_ramp) {
|
||||
map->ramped_twist_tempi (prev, focus, next, initial_pre_npm + delta);
|
||||
} else {
|
||||
map->linear_twist_tempi (prev, focus, next, initial_focus_npm + delta);
|
||||
}
|
||||
_editor->mid_tempo_change (Editor::MappingChanged);
|
||||
}
|
||||
|
||||
|
|
|
@ -912,10 +912,10 @@ private:
|
|||
XMLNode* _before_state;
|
||||
};
|
||||
|
||||
class MappingLinearDrag : public Drag
|
||||
class MappingEndDrag : public Drag
|
||||
{
|
||||
public:
|
||||
MappingLinearDrag (Editor *, ArdourCanvas::Item *, Temporal::TempoMap::WritableSharedPtr&, Temporal::TempoPoint&, Temporal::TempoPoint& after, XMLNode& before_state);
|
||||
MappingEndDrag (Editor *, ArdourCanvas::Item *, Temporal::TempoMap::WritableSharedPtr&, Temporal::TempoPoint&, Temporal::TempoPoint& after, XMLNode& before_state);
|
||||
|
||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||
void motion (GdkEvent *, bool);
|
||||
|
@ -975,7 +975,8 @@ private:
|
|||
|
||||
double direction;
|
||||
double delta;
|
||||
double initial_npm;
|
||||
double initial_focus_npm;
|
||||
double initial_pre_npm;
|
||||
|
||||
XMLNode* _before_state;
|
||||
bool _drag_valid;
|
||||
|
|
|
@ -2924,6 +2924,13 @@ Editor::get_pointer_position (double& x, double& y) const
|
|||
void
|
||||
Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
/* In a departure from convention, this event is not handled by a widget
|
||||
* 'on' the ruler-bar, like a tempo marker, but is instead handled by the
|
||||
* mapping-bar widget itself. The intent is for the user to feel that they
|
||||
* are manipulating the 'beat and bar grid' which may or may not have tempo
|
||||
* markers already assigned at the point under the mouse.
|
||||
*/
|
||||
|
||||
if (item != mapping_bar) {
|
||||
return;
|
||||
}
|
||||
|
@ -2935,9 +2942,9 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
|
||||
Temporal::TempoMap::WritableSharedPtr map = begin_tempo_mapping ();
|
||||
|
||||
/* Decide between a tempo twist drag, which we do if the
|
||||
* pointer is between two tempo markers, and a tempo stretch
|
||||
* drag, which we do if the pointer is after the last tempo
|
||||
/* Decide between a mid-twist, which we do if the
|
||||
* pointer is between two tempo markers, and an end-stretch,
|
||||
* which we do if the pointer is after the last tempo
|
||||
* marker before the end of the map or a BBT Marker.
|
||||
*/
|
||||
|
||||
|
@ -2952,17 +2959,38 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
TempoPoint* before;
|
||||
TempoPoint* focus;
|
||||
|
||||
bool stretch = false;
|
||||
|
||||
bool at_end = false;
|
||||
if (!after || dynamic_cast<MusicTimePoint*>(after)) {
|
||||
stretch = true;
|
||||
at_end = true;
|
||||
}
|
||||
|
||||
BBT_Argument bbt = map->bbt_at (pointer_time);
|
||||
bbt = BBT_Argument (bbt.reference(), bbt.round_to_beat ());
|
||||
|
||||
if (tempo.bbt() != bbt) {
|
||||
/* BBT_Argument is meter-agnostic so we need to use the map's meter to resolve bar boundaries */
|
||||
const Meter& m = map->meter_at (pointer_time);
|
||||
if (bbt.beats > m.divisions_per_bar()){
|
||||
bbt.beats = 1;
|
||||
bbt.bars++;
|
||||
}
|
||||
|
||||
if (tempo.bbt() == bbt) {
|
||||
std::cerr << "we are on the RIGHT side of an EXISTING tempo marker" << bbt << " == " << tempo.bbt() << "\n";
|
||||
|
||||
before = const_cast<TempoPoint*> (map->previous_tempo (tempo));
|
||||
focus = &tempo;
|
||||
|
||||
} else if ((after && after->bbt() == bbt )) {
|
||||
std::cerr << "we are on the LEFT side of an EXISTING tempo marker" << bbt << " == " << after->bbt() << "\n";
|
||||
|
||||
before = const_cast<TempoPoint*> (&tempo);
|
||||
focus = after;
|
||||
after = const_cast<TempoPoint*> (map->next_tempo (*focus));
|
||||
if (!after) {
|
||||
at_end = true; //but it's the last one, so we're operating on the last
|
||||
}
|
||||
|
||||
} else {
|
||||
std::cerr << "ADD TEMPO MARKER " << bbt << " != " << tempo.bbt() << "\n";
|
||||
|
||||
/* Add a new tempo marker at the nearest beat point
|
||||
|
@ -2978,32 +3006,20 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
reset_tempo_marks ();
|
||||
|
||||
map->dump (std::cerr);
|
||||
|
||||
} else {
|
||||
|
||||
std::cerr << "USE TEMPO MARKER\n";
|
||||
|
||||
before = const_cast<TempoPoint*> (map->previous_tempo (tempo));
|
||||
|
||||
if (!before) {
|
||||
delete before_state;
|
||||
return;
|
||||
}
|
||||
|
||||
focus = &tempo;
|
||||
}
|
||||
|
||||
/* Reversible commands start here, must be ended/aborted in drag */
|
||||
|
||||
if (stretch) {
|
||||
begin_reversible_command (_("map tempo/stretch"));
|
||||
std::cerr << "STRETCH\n";
|
||||
_drags->set (new MappingLinearDrag (this, item, map, tempo, *focus, *before_state), event);
|
||||
if (at_end) {
|
||||
begin_reversible_command (_("tempo mapping: end-stretch"));
|
||||
std::cerr << "END STRETCH\n";
|
||||
_drags->set (new MappingEndDrag (this, item, map, tempo, *focus, *before_state), event);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::cerr << "TWIST\n";
|
||||
begin_reversible_command (_("map tempo/twist"));
|
||||
_drags->set (new MappingTwistDrag (this, item, map, *before, *focus, *after, *before_state), event);
|
||||
if (before && focus && after) {
|
||||
std::cerr << "TWIST\n";
|
||||
begin_reversible_command (_("tempo mapping: mid-twist"));
|
||||
_drags->set (new MappingTwistDrag (this, item, map, *before, *focus, *after, *before_state), event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3631,7 +3631,49 @@ TempoMap::iteratively_solve_ramp (TempoPoint& earlier, TempoPoint& later)
|
|||
}
|
||||
|
||||
void
|
||||
TempoMap::twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
||||
TempoMap::linear_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
||||
{
|
||||
/* Check if the new tempo value is within an acceptable range */
|
||||
|
||||
if (tempo_value < 4.0 || tempo_value > 400) {
|
||||
return;
|
||||
}
|
||||
|
||||
TempoPoint old_prev (prev);
|
||||
TempoPoint old_focus (focus);
|
||||
|
||||
/* Our job here is to reposition @param focus without altering the
|
||||
* positions of @param prev and @param next. We do this by changing
|
||||
* the tempo of prev (as opposed to ramped_twist_tempi, below )
|
||||
*/
|
||||
|
||||
/* set a fixed tempo for the previous marker (this results in 'focus' moving a bit with the mouse) */
|
||||
prev.set_note_types_per_minute (tempo_value);
|
||||
prev.set_end_npm (tempo_value);
|
||||
|
||||
/* reposition focus, using prev to define audio time; leave beat time
|
||||
* and BBT alone
|
||||
*/
|
||||
|
||||
focus.set (prev.superclock_at (focus.beats()), focus.beats(), focus.bbt());
|
||||
|
||||
/* Now iteratively adjust focus.superclocks_per_quarter_note() (the
|
||||
* section's starting tempo) so that next.sclock() remains within 1
|
||||
* sample of its current position
|
||||
*/
|
||||
|
||||
std::cerr << "pre-iter\n";
|
||||
dump (std::cerr);
|
||||
|
||||
if (!iteratively_solve_ramp (focus, next)) {
|
||||
prev = old_prev;
|
||||
focus = old_focus;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::ramped_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
||||
{
|
||||
/* Check if the new tempo value is within an acceptable range */
|
||||
|
||||
|
|
|
@ -766,7 +766,9 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
|
|||
|
||||
LIBTEMPORAL_API int set_state (XMLNode const&, int version);
|
||||
|
||||
LIBTEMPORAL_API void twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_delta);
|
||||
LIBTEMPORAL_API void linear_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_delta);
|
||||
LIBTEMPORAL_API void ramped_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_delta);
|
||||
|
||||
LIBTEMPORAL_API void stretch_tempo (TempoPoint& ts, double new_npm);
|
||||
LIBTEMPORAL_API void stretch_tempo_end (TempoPoint* ts, samplepos_t sample, samplepos_t end_sample);
|
||||
|
||||
|
|
Loading…
Reference in New Issue