Compare commits
5 Commits
f1f352a6e9
...
ed7683d029
Author | SHA1 | Date |
---|---|---|
Ben Loftis | ed7683d029 | |
Ben Loftis | a217c58ff5 | |
Ben Loftis | ca5e56f98c | |
Ben Loftis | c452a4816c | |
Ben Loftis | 9fa8e257a6 |
|
@ -518,7 +518,7 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!from_autoscroll) {
|
if (!from_autoscroll) {
|
||||||
_editor->maybe_autoscroll (true, allow_vertical_autoscroll (), false);
|
_editor->maybe_autoscroll (allow_horizontal_autoscroll (), allow_vertical_autoscroll (), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_editor->autoscroll_active() || from_autoscroll) {
|
if (!_editor->autoscroll_active() || from_autoscroll) {
|
||||||
|
@ -3588,7 +3588,8 @@ MappingTwistDrag::MappingTwistDrag (Editor* e, ArdourCanvas::Item* i, Temporal::
|
||||||
TempoPoint& prv,
|
TempoPoint& prv,
|
||||||
TempoPoint& fcus,
|
TempoPoint& fcus,
|
||||||
TempoPoint& nxt,
|
TempoPoint& nxt,
|
||||||
XMLNode& before)
|
XMLNode& before,
|
||||||
|
bool ramped)
|
||||||
: Drag (e, i, Temporal::BeatTime)
|
: Drag (e, i, Temporal::BeatTime)
|
||||||
, prev (prv)
|
, prev (prv)
|
||||||
, focus (fcus)
|
, focus (fcus)
|
||||||
|
@ -3598,6 +3599,7 @@ MappingTwistDrag::MappingTwistDrag (Editor* e, ArdourCanvas::Item* i, Temporal::
|
||||||
, delta (0.)
|
, delta (0.)
|
||||||
, _before_state (&before)
|
, _before_state (&before)
|
||||||
, _drag_valid (true)
|
, _drag_valid (true)
|
||||||
|
, _do_ramp (ramped)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New MappingTwistDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New MappingTwistDrag\n");
|
||||||
initial_focus_npm = focus.note_types_per_minute ();
|
initial_focus_npm = focus.note_types_per_minute ();
|
||||||
|
@ -3644,12 +3646,6 @@ MappingTwistDrag::motion (GdkEvent* event, bool first_move)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_drags->current_pointer_time() >= timepos_t::from_superclock (next.sclock())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_drags->current_pointer_time() <= timepos_t::from_superclock (prev.sclock())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX needs to scale somehow with zoom level */
|
/* XXX needs to scale somehow with zoom level */
|
||||||
|
|
||||||
|
@ -3660,11 +3656,10 @@ MappingTwistDrag::motion (GdkEvent* event, bool first_move)
|
||||||
delta += scaling_factor * pixel_distance;
|
delta += scaling_factor * pixel_distance;
|
||||||
std::cerr << "pixels " << pixel_distance << " spp " << spp << " SF " << scaling_factor << " delta = " << delta << std::endl;
|
std::cerr << "pixels " << pixel_distance << " spp " << spp << " SF " << scaling_factor << " delta = " << delta << std::endl;
|
||||||
|
|
||||||
bool do_a_ramp = true; // @ben
|
if (_do_ramp) {
|
||||||
if (do_a_ramp) {
|
map->ramped_twist_tempi (prev, focus, next, initial_focus_npm + delta); //was: PRE ... maybe we don't need 2 anymore?
|
||||||
map->ramped_twist_tempi (prev, focus, next, initial_pre_npm + delta);
|
|
||||||
} else {
|
} else {
|
||||||
map->linear_twist_tempi (prev, focus, next, initial_focus_npm + delta);
|
map->constant_twist_tempi (prev, focus, next, initial_focus_npm + delta);
|
||||||
}
|
}
|
||||||
_editor->mid_tempo_change (Editor::MappingChanged);
|
_editor->mid_tempo_change (Editor::MappingChanged);
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,6 +220,10 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool allow_horizontal_autoscroll () const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return true if x movement matters to this drag */
|
/** @return true if x movement matters to this drag */
|
||||||
virtual bool x_movement_matters () const {
|
virtual bool x_movement_matters () const {
|
||||||
return true;
|
return true;
|
||||||
|
@ -926,6 +930,10 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool allow_horizontal_autoscroll () const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool y_movement_matters () const {
|
bool y_movement_matters () const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -949,7 +957,8 @@ public:
|
||||||
Temporal::TempoPoint& prev,
|
Temporal::TempoPoint& prev,
|
||||||
Temporal::TempoPoint& focus,
|
Temporal::TempoPoint& focus,
|
||||||
Temporal::TempoPoint& next,
|
Temporal::TempoPoint& next,
|
||||||
XMLNode&);
|
XMLNode&,
|
||||||
|
bool ramped);
|
||||||
|
|
||||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||||
void motion (GdkEvent *, bool);
|
void motion (GdkEvent *, bool);
|
||||||
|
@ -960,6 +969,10 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool allow_horizontal_autoscroll () const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool y_movement_matters () const {
|
bool y_movement_matters () const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -980,6 +993,7 @@ private:
|
||||||
|
|
||||||
XMLNode* _before_state;
|
XMLNode* _before_state;
|
||||||
bool _drag_valid;
|
bool _drag_valid;
|
||||||
|
bool _do_ramp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2348,6 +2348,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, bool from_aut
|
||||||
|
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
timepos_t snapped = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBeat);
|
timepos_t snapped = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBeat);
|
||||||
|
timepos_t snapped_to_bar = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBar);
|
||||||
const double unsnapped_pos = time_to_pixel_unrounded (t);
|
const double unsnapped_pos = time_to_pixel_unrounded (t);
|
||||||
const double snapped_pos = time_to_pixel_unrounded (snapped);
|
const double snapped_pos = time_to_pixel_unrounded (snapped);
|
||||||
|
|
||||||
|
@ -2358,7 +2359,12 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, bool from_aut
|
||||||
* the beat.
|
* the beat.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ctx->cursor_ctx->change (cursors()->time_fx);
|
if (snapped == snapped_to_bar) {
|
||||||
|
ctx->cursor_ctx->change (cursors()->time_fx);
|
||||||
|
} else {
|
||||||
|
/* snapped to a beat, not a bar .... we'll implement a TWIST here */
|
||||||
|
ctx->cursor_ctx->change (cursors()->expand_left_right);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx->cursor_ctx->change (cursors()->grabber);
|
ctx->cursor_ctx->change (cursors()->grabber);
|
||||||
}
|
}
|
||||||
|
@ -2938,7 +2944,18 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cursor_stack.empty() || _cursor_stack.back() != cursors()->time_fx) {
|
if (_cursor_stack.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ramped = false;
|
||||||
|
if (_cursor_stack.back() == cursors()->time_fx) {
|
||||||
|
/* We are on a BAR line ... the user can drag the line exactly where it's needed */
|
||||||
|
ramped = false;
|
||||||
|
} else if (_cursor_stack.back() == cursors()->expand_left_right) {
|
||||||
|
/* We are on a BEAT line ... we will nudge the beat line via ramping, without moving any tempo markers */
|
||||||
|
ramped = true;
|
||||||
|
} else {
|
||||||
/* Not close enough to a beat line to start any mapping drag */
|
/* Not close enough to a beat line to start any mapping drag */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3001,10 +3018,17 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
||||||
|
|
||||||
/* special case 3: if we are on the left side of the LAST marker: behave as if we clicked the marker prior*/
|
/* special case 3: if we are on the left side of the LAST marker: behave as if we clicked the marker prior*/
|
||||||
TempoPoint* after_after = const_cast<TempoPoint*> (map->next_tempo (*focus));
|
TempoPoint* after_after = const_cast<TempoPoint*> (map->next_tempo (*focus));
|
||||||
if (!after_after) {
|
if (after_after) {
|
||||||
|
after = after_after;
|
||||||
|
} else {
|
||||||
at_end = true;
|
at_end = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (ramped) {
|
||||||
|
|
||||||
|
/* User is dragging on a BEAT line (not a bar line) ... try to implement a tempo twist on the prior marker */
|
||||||
|
focus = &tempo;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "ADD TEMPO MARKER " << bbt << " != " << tempo.bbt() << "\n";
|
std::cerr << "ADD TEMPO MARKER " << bbt << " != " << tempo.bbt() << "\n";
|
||||||
|
|
||||||
|
@ -3035,6 +3059,6 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
||||||
if (before && focus && after) {
|
if (before && focus && after) {
|
||||||
std::cerr << "TWIST\n";
|
std::cerr << "TWIST\n";
|
||||||
begin_reversible_command (_("tempo mapping: mid-twist"));
|
begin_reversible_command (_("tempo mapping: mid-twist"));
|
||||||
_drags->set (new MappingTwistDrag (this, item, map, *before, *focus, *after, *before_state), event);
|
_drags->set (new MappingTwistDrag (this, item, map, *before, *focus, *after, *before_state, ramped), event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3706,14 +3706,14 @@ TempoMap::stretch_tempo_end (TempoPoint* ts, samplepos_t sample, samplepos_t end
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TempoMap::iteratively_solve_ramp (TempoPoint& earlier, TempoPoint& later)
|
TempoMap::solve_ramped_twist (TempoPoint& earlier, TempoPoint& later)
|
||||||
{
|
{
|
||||||
superclock_t err = earlier.superclock_at (later.beats()) - later.sclock();
|
superclock_t err = earlier.superclock_at (later.beats()) - later.sclock();
|
||||||
const superclock_t one_sample = superclock_ticks_per_second() / TEMPORAL_SAMPLE_RATE;
|
const superclock_t one_sample = superclock_ticks_per_second() / TEMPORAL_SAMPLE_RATE;
|
||||||
const Beats b (later.beats() - earlier.beats());
|
const Beats b (later.beats() - earlier.beats());
|
||||||
const double end_scpqn = earlier.end_superclocks_per_quarter_note();
|
double end_scpqn = earlier.end_superclocks_per_quarter_note();
|
||||||
double scpqn = earlier.superclocks_per_quarter_note ();
|
double start_scpqn = earlier.superclocks_per_quarter_note ();
|
||||||
double new_npm;
|
double new_end_npm;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
while (std::abs(err) >= one_sample) {
|
while (std::abs(err) >= one_sample) {
|
||||||
|
@ -3722,26 +3722,26 @@ TempoMap::iteratively_solve_ramp (TempoPoint& earlier, TempoPoint& later)
|
||||||
/* estimated > actual: speed end tempo up a little aka
|
/* estimated > actual: speed end tempo up a little aka
|
||||||
reduce scpqn
|
reduce scpqn
|
||||||
*/
|
*/
|
||||||
scpqn *= 0.99;
|
end_scpqn *= 0.99;
|
||||||
} else {
|
} else {
|
||||||
/* estimated < actual: reduce end tempo a little, aka
|
/* estimated < actual: reduce end tempo a little, aka
|
||||||
increase scpqn
|
increase scpqn
|
||||||
*/
|
*/
|
||||||
scpqn *= 1.01;
|
end_scpqn *= 1.01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scpqn < 1.0) {
|
if (end_scpqn < 1.0) {
|
||||||
/* mathematically too small, bail out */
|
/* mathematically too small, bail out */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert scpqn to notes-per-minute */
|
/* Convert scpqn to notes-per-minute */
|
||||||
|
|
||||||
new_npm = ((superclock_ticks_per_second() * 60.0) / scpqn) * (earlier.note_type() / 4.0);
|
new_end_npm = ((superclock_ticks_per_second() * 60.0) / end_scpqn) * (earlier.note_type() / 4.0);
|
||||||
|
|
||||||
/* limit range of possible discovered tempo */
|
/* limit range of possible discovered tempo */
|
||||||
|
|
||||||
if (new_npm < 4.0 && new_npm > 400) {
|
if (new_end_npm < 4.0 && new_end_npm > 400) {
|
||||||
/* too low of a tempo for our taste, bail out */
|
/* too low of a tempo for our taste, bail out */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3751,12 +3751,70 @@ TempoMap::iteratively_solve_ramp (TempoPoint& earlier, TempoPoint& later)
|
||||||
* the later marker and its actual (fixed) position.
|
* the later marker and its actual (fixed) position.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
earlier.set_note_types_per_minute (new_npm);
|
earlier.set_end_npm (new_end_npm);
|
||||||
earlier.compute_omega_beats_from_quarter_duration (b, end_scpqn);
|
earlier.compute_omega_beats_from_next_tempo (later);
|
||||||
err = earlier.superclock_at (later.beats()) - later.sclock();
|
err = earlier.superclock_at (later.beats()) - later.sclock();
|
||||||
if (cnt % 1000 == 0) {
|
|
||||||
std::cerr << "nn: " << new_npm << " err " << err << " @ " << cnt << std::endl;
|
if (cnt > 20000) {
|
||||||
|
std::cerr << "nn: " << new_end_npm << " err " << err << " @ " << cnt << "solve_ramped_twist FAILED\n";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "that took " << cnt << " iterations to get to < 1 sample\n";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TempoMap::solve_constant_twist (TempoPoint& earlier, TempoPoint& later)
|
||||||
|
{
|
||||||
|
superclock_t err = earlier.superclock_at (later.beats()) - later.sclock();
|
||||||
|
const superclock_t one_sample = superclock_ticks_per_second() / TEMPORAL_SAMPLE_RATE;
|
||||||
|
const Beats b (later.beats() - earlier.beats());
|
||||||
|
double start_npm = earlier.superclocks_per_quarter_note ();
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
while (std::abs(err) >= one_sample) {
|
||||||
|
|
||||||
|
if (err > 0) {
|
||||||
|
/* estimated > actual: speed end tempo up a little aka
|
||||||
|
reduce scpqn
|
||||||
|
*/
|
||||||
|
start_npm *= 0.99;
|
||||||
|
} else {
|
||||||
|
/* estimated < actual: reduce end tempo a little, aka
|
||||||
|
increase scpqn
|
||||||
|
*/
|
||||||
|
start_npm *= 1.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert scpqn to notes-per-minute */
|
||||||
|
|
||||||
|
double new_npm = ((superclock_ticks_per_second() * 60.0) / start_npm) * (earlier.note_type() / 4.0);
|
||||||
|
|
||||||
|
/* limit range of possible discovered tempo */
|
||||||
|
|
||||||
|
if (new_npm < 4.0 && new_npm > 400) {
|
||||||
|
/* too low of a tempo for our taste, bail out */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the (initial) tempo, and then compute
|
||||||
|
* the (new) error (distance between the predicted position of
|
||||||
|
* the later marker and its actual (fixed) position.
|
||||||
|
*/
|
||||||
|
earlier.set_note_types_per_minute (new_npm);
|
||||||
|
earlier.set_end_npm (new_npm);
|
||||||
|
err = earlier.superclock_at (later.beats()) - later.sclock();
|
||||||
|
|
||||||
|
if (cnt > 20000) {
|
||||||
|
std::cerr << "nn: " << new_npm << " err " << err << " @ " << cnt << "solve_constant_twist FAILED\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3766,11 +3824,12 @@ TempoMap::iteratively_solve_ramp (TempoPoint& earlier, TempoPoint& later)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TempoMap::linear_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
TempoMap::constant_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
||||||
{
|
{
|
||||||
/* Check if the new tempo value is within an acceptable range */
|
/* Check if the new tempo value is within an acceptable range */
|
||||||
|
|
||||||
if (tempo_value < 4.0 || tempo_value > 400) {
|
if (tempo_value < 4.0 || tempo_value > 400) {
|
||||||
|
std::cerr << "can't set tempo to " << tempo_value << " ....fail\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3800,15 +3859,16 @@ TempoMap::linear_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& n
|
||||||
std::cerr << "pre-iter\n";
|
std::cerr << "pre-iter\n";
|
||||||
dump (std::cerr);
|
dump (std::cerr);
|
||||||
|
|
||||||
if (!iteratively_solve_ramp (focus, next)) {
|
if (!solve_constant_twist (focus, next)) {
|
||||||
prev = old_prev;
|
prev = old_prev;
|
||||||
focus = old_focus;
|
focus = old_focus;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TempoMap::ramped_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
TempoMap::ramped_twist_tempi (TempoPoint& unused, TempoPoint& focus, TempoPoint& next, double tempo_value)
|
||||||
{
|
{
|
||||||
/* Check if the new tempo value is within an acceptable range */
|
/* Check if the new tempo value is within an acceptable range */
|
||||||
|
|
||||||
|
@ -3816,11 +3876,12 @@ TempoMap::ramped_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& n
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Our job here is to reposition @param focus without altering the
|
/* Our job here is to tweak the ramp of @param focus without
|
||||||
* tempos or positions of @param prev and @param next. We are
|
* altering the positions of @param focus and @param next.
|
||||||
* "twisting" the tempo section before and after focus
|
* We are "twisting" the tempo section between those markers
|
||||||
|
* to enact a change but without moving the markers themselves
|
||||||
*
|
*
|
||||||
* Start by saving the current state of prev and focus in case we need
|
* Start by saving the current state of focus in case we need
|
||||||
* to bail out because change is impossible.
|
* to bail out because change is impossible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3828,52 +3889,19 @@ TempoMap::ramped_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& n
|
||||||
dump (std::cerr);
|
dump (std::cerr);
|
||||||
std::cerr << "----------------------------\n";
|
std::cerr << "----------------------------\n";
|
||||||
|
|
||||||
TempoPoint old_prev (prev);
|
|
||||||
TempoPoint old_focus (focus);
|
TempoPoint old_focus (focus);
|
||||||
|
|
||||||
/* fix end tempo of prev tempo marker then recompute its omega */
|
/* set start tempo of prev tempo marker; we will iteratively solve for the required ramp value */
|
||||||
prev.set_end_npm (tempo_value);
|
|
||||||
prev.compute_omega_beats_from_next_tempo (focus);
|
|
||||||
|
|
||||||
/* 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());
|
|
||||||
|
|
||||||
/* set focus start & end tempos appropriately */
|
|
||||||
|
|
||||||
focus.set_note_types_per_minute (tempo_value);
|
focus.set_note_types_per_minute (tempo_value);
|
||||||
|
|
||||||
/* recompute focus omega */
|
|
||||||
|
|
||||||
focus.compute_omega_beats_from_next_tempo (next);
|
|
||||||
|
|
||||||
/* 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";
|
std::cerr << "pre-iter\n";
|
||||||
dump (std::cerr);
|
dump (std::cerr);
|
||||||
|
|
||||||
if (!iteratively_solve_ramp (focus, next)) {
|
if (!solve_ramped_twist (focus, next)) {
|
||||||
prev = old_prev;
|
|
||||||
focus = old_focus;
|
focus = old_focus;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
prev.set_end_npm (focus.note_types_per_minute());
|
|
||||||
prev.compute_omega_beats_from_next_tempo (focus);
|
|
||||||
|
|
||||||
if (!iteratively_solve_ramp (prev, focus)) {
|
|
||||||
prev = old_prev;
|
|
||||||
focus = old_focus;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::cerr << "Twisted with " << tempo_value << std::endl;
|
std::cerr << "Twisted with " << tempo_value << std::endl;
|
||||||
dump (std::cerr);
|
dump (std::cerr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -767,7 +767,7 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
|
||||||
|
|
||||||
LIBTEMPORAL_API int set_state (XMLNode const&, int version);
|
LIBTEMPORAL_API int set_state (XMLNode const&, int version);
|
||||||
|
|
||||||
LIBTEMPORAL_API void linear_twist_tempi (TempoPoint& prev, TempoPoint& focus, TempoPoint& next, double tempo_delta);
|
LIBTEMPORAL_API void constant_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 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 (TempoPoint& ts, double new_npm);
|
||||||
|
@ -1129,7 +1129,8 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
|
||||||
Temporal::BBT_Time bbt_lookup (superclock_t, bool & found) const;
|
Temporal::BBT_Time bbt_lookup (superclock_t, bool & found) const;
|
||||||
Temporal::BBT_Time bbt_lookup (Temporal::Beats const & b, bool & found) const;
|
Temporal::BBT_Time bbt_lookup (Temporal::Beats const & b, bool & found) const;
|
||||||
|
|
||||||
bool iteratively_solve_ramp (TempoPoint&, TempoPoint&);
|
bool solve_ramped_twist (TempoPoint&, TempoPoint&); /* this is implemented by iteration, and it might fail. */
|
||||||
|
bool solve_constant_twist (TempoPoint&, TempoPoint&); //TODO: currently also done by iteration; should be possible to calculate directly
|
||||||
|
|
||||||
bool core_remove_meter (MeterPoint const &);
|
bool core_remove_meter (MeterPoint const &);
|
||||||
bool core_remove_tempo (TempoPoint const &);
|
bool core_remove_tempo (TempoPoint const &);
|
||||||
|
|
Loading…
Reference in New Issue