VKeybd: exponential pitch-wheel/bend interpolation

This commit is contained in:
Robin Gareus 2019-12-17 16:47:46 +01:00
parent 37c9a7beb1
commit 9c6d9324bd
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 19 additions and 15 deletions

View file

@ -599,11 +599,12 @@ APianoKeyboard::handle_fixed_keys (GdkEventKey* ev)
case GDK_KEY_F3: case GDK_KEY_F3:
/* fallthrough */ /* fallthrough */
case GDK_KEY_F4: case GDK_KEY_F4:
/* fallthrough */ PitchBend (8192, false);
break;
case GDK_KEY_Up: case GDK_KEY_Up:
/* fallthrough */ /* fallthrough */
case GDK_KEY_Down: case GDK_KEY_Down:
PitchBend (8192, false); PitchBend (8192, true);
return true; return true;
default: default:
break; break;

View file

@ -564,14 +564,17 @@ VirtualKeyboardWindow::octave_key_event_handler (bool up)
void void
VirtualKeyboardWindow::pitch_bend_key_event_handler (int target, bool interpolate) VirtualKeyboardWindow::pitch_bend_key_event_handler (int target, bool interpolate)
{ {
if (_pitch_adjustment.get_value() == target) { int cur = _pitch_adjustment.get_value();
if (cur == target) {
return; return;
} }
if (interpolate) { if (interpolate) {
_pitch_bend_target = target; _pitch_bend_target = target;
if (!_bender_connection.connected ()){ if (!_bender_connection.connected ()) {
_bender_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::pitch_bend_timeout), 40 /*ms*/); float tc = _pitch_bend_target == 8192 ? .35 : .51;
} else { cur = rintf (cur + tc * (_pitch_bend_target - cur));
_pitch_adjustment.set_value (cur);
_bender_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &VirtualKeyboardWindow::pitch_bend_timeout), 20 /*ms*/);
} }
return; return;
} }
@ -584,16 +587,16 @@ bool
VirtualKeyboardWindow::pitch_bend_timeout () VirtualKeyboardWindow::pitch_bend_timeout ()
{ {
int cur = _pitch_adjustment.get_value(); int cur = _pitch_adjustment.get_value();
int target;
if (cur < _pitch_bend_target) { /* a spring would be 2nd order with overshoot,
target = std::min (_pitch_bend_target, cur + 1024); * but we assume it's critically damped */
} else if (cur > _pitch_bend_target) { float tc = _pitch_bend_target == 8192 ? .35 : .51;
target = std::max (_pitch_bend_target, cur - 1024); cur = rintf (cur + tc * (_pitch_bend_target - cur));
} else { if (abs (cur - _pitch_bend_target) < 2) {
target = _pitch_bend_target; cur = _pitch_bend_target;
} }
_pitch_adjustment.set_value (target); _pitch_adjustment.set_value (cur);
return _pitch_bend_target != target; return _pitch_bend_target != cur;
} }
void void