robert@464: /* robert@464: * robert@464: * Plectrum model for touching and plucking strings robert@464: * robert@464: * Christian Heinrichs 04/2015 robert@464: * robert@464: * [inspired by E. Berdahl's pluck~ abstraction for the FireFader] robert@464: * robert@464: */ robert@464: robert@464: #include "Plectrum.h" robert@464: robert@464: #include "../include/Utilities.h" robert@464: #include robert@464: #include robert@464: #include robert@464: robert@464: Plectrum::Plectrum() { robert@464: robert@464: _contact = 0; robert@464: _lastDistance = 0; robert@464: robert@464: } robert@464: robert@464: void Plectrum::setup(float spring, float damp, float hyst) { robert@464: robert@464: _spring = spring; robert@464: _damp = damp; robert@464: _hyst = hyst; robert@464: robert@464: } robert@464: robert@464: float Plectrum::update(float position, float stringPosition) { robert@464: robert@464: float distance = position - stringPosition; robert@464: robert@464: // Calculate spring/damp forces based on distance to string robert@464: robert@464: float springOut = distance * _spring; robert@464: robert@464: float dampOut = (distance - _lastDistance) * 44100; robert@464: robert@464: float out = springOut+dampOut; robert@464: robert@464: // If distance crosses zero, enable contact robert@464: robert@464: if((distance>0 && _lastDistance<=0)||(distance<0 && _lastDistance>=0)) robert@464: _contact = 1; robert@464: robert@464: // If distance exceeds hysteresis threshold, jump to zero (i.e. 'pluck') robert@464: robert@464: if(fabs(distance)>_hyst) robert@464: _contact = 0; robert@464: robert@464: // FIXME: contact doesn't switch back to zero if distance goes back in original direction robert@464: robert@464: _lastDistance = distance; robert@464: robert@464: return out * _contact; robert@464: robert@464: }