Mixer: Try to better cope with parameter feedback feedback cycles.

pull/119/merge
Jonathan Moore Liles 2020-11-19 18:48:41 -08:00
parent 1f0f01c0ad
commit 82f9610ca8
6 changed files with 82 additions and 23 deletions

View File

@ -49,7 +49,8 @@
#include "Controller_Module.H"
const double FEEDBACK_UPDATE_FREQ = 1.0f;
/* const double FEEDBACK_UPDATE_FREQ = 1.0f; */
const double FEEDBACK_UPDATE_FREQ = 1.0f / 30.0f;
extern char *user_config_dir;
extern char *instance_name;
@ -593,7 +594,6 @@ Mixer::Mixer ( int X, int Y, int W, int H, const char *L ) :
update_frequency( 24 );
Fl::add_timeout( FEEDBACK_UPDATE_FREQ, send_feedback_cb, this );
update_menu();
@ -1078,6 +1078,7 @@ Mixer::send_feedback_cb ( void *v )
m->send_feedback();
/* just to it once at the start... */
Fl::repeat_timeout( FEEDBACK_UPDATE_FREQ, send_feedback_cb, v );
}
@ -1297,6 +1298,9 @@ Mixer::command_load ( const char *path, const char *display_name )
mixer->activate();
/* Fl::remove_timeout( send_feedback_cb, this ); */
Fl::add_timeout( FEEDBACK_UPDATE_FREQ, send_feedback_cb, this );
return true;
}

View File

@ -48,6 +48,9 @@
#include "string_util.h"
#include "time.h"
nframes_t Module::_sample_rate = 0;
@ -166,7 +169,8 @@ Module::init ( void )
_chain = 0;
_instances = 1;
_bypass = 0;
_pending_feedback = false;
box( FL_UP_BOX );
labeltype( FL_NO_LABEL );
align( FL_ALIGN_CENTER | FL_ALIGN_INSIDE );
@ -331,8 +335,11 @@ Module::Port::osc_number_path ( void )
}
void
Module::Port::send_feedback ( void )
Module::Port::send_feedback ( bool force )
{
if ( !_pending_feedback )
return;
float f = control_value();
if ( hints.ranged )
@ -345,18 +352,39 @@ Module::Port::send_feedback ( void )
f = ( f - offset ) / scale;
}
if ( f > 1.0 )
f = 1.0;
else if ( f < 0.0 )
f = 0.0;
if ( f > 1.0f )
f = 1.0f;
else if ( f < 0.0f )
f = 0.0f;
/* struct timespec t; */
/* clock_gettime( CLOCK_MONOTONIC, &t ); */
/* /\* don't send feedback more at more than 30Hz rate. *\/ */
/* unsigned long long ms = (t.tv_sec * 1000 + ( t.tv_nsec / 1000000 )); */
/* if ( ms - _feedback_milliseconds < 1000 / 30 ) */
/* return; */
/* _feedback_milliseconds = ms; */
if ( _scaled_signal )
{
/* send feedback for by_name signal */
mixer->osc_endpoint->send_feedback( _scaled_signal->path(), f );
/* send feedback for by number signal */
mixer->osc_endpoint->send_feedback( osc_number_path(), f );
if ( fabsf( _feedback_value - f ) > (1.0f / 128.0f) )
{
/* only send feedback if value has changed significantly since the last time we sent it. */
/* DMESSAGE( "signal value: %f, controL_value: %f", _scaled_signal->value(), f ); */
/* send feedback for by_name signal */
mixer->osc_endpoint->send_feedback( _scaled_signal->path(), f );
/* send feedback for by number signal */
mixer->osc_endpoint->send_feedback( osc_number_path(), f );
_feedback_value = f;
_pending_feedback = false;
/* _scaled_signal->value( f ); */
}
}
}
@ -364,7 +392,7 @@ void
Module::send_feedback ( void )
{
for ( int i = 0; i < ncontrol_inputs(); i++ )
control_input[i].send_feedback();
control_input[i].send_feedback(true);
}
void
@ -373,7 +401,11 @@ Module::handle_control_changed ( Port *p )
if ( _editor )
_editor->handle_control_changed ( p );
p->send_feedback();
p->schedule_feedback();
/* DMESSAGE("Control changed"); */
/* p->send_feedback(false); */
}
/* bool */

View File

@ -48,7 +48,8 @@ class Module : public Fl_Group, public Loggable {
int _instances;
Chain *_chain;
bool _is_default;
bool _pending_feedback;
nframes_t _nframes;
static nframes_t _sample_rate;
static Module *_copied_module_empty;
@ -103,6 +104,7 @@ public:
connected_port()->_buf = _buf;
}
public:
enum Direction { INPUT, OUTPUT };
@ -120,7 +122,7 @@ public:
float default_value;
int dimensions;
bool visible;
Hints ( )
{
type = LINEAR;
@ -153,6 +155,9 @@ public:
_by_number_path = 0;
_by_number_number = -1;
_jack_port = 0;
_feedback_value = -2;
_pending_feedback = false;
_feedback_milliseconds = 0;
}
Port ( const Port& p )
@ -169,6 +174,7 @@ public:
_by_number_path = 0;
_by_number_number = -1;
_jack_port = p._jack_port;
_feedback_value = p._feedback_value;
}
virtual ~Port ( )
@ -299,7 +305,7 @@ public:
_buf = buf;
}
void send_feedback ( void );
void send_feedback ( bool force );
bool connected_to ( Port *p )
{
@ -332,6 +338,8 @@ public:
void jack_port ( JACK::Port *v ) { _jack_port = v; }
JACK::Port *jack_port ( void ) const { return _jack_port; }
void schedule_feedback ( void ) { _pending_feedback = true; }
private:
char *generate_osc_path ( void );
@ -350,6 +358,10 @@ public:
OSC::Signal *_scaled_signal;
OSC::Signal *_unscaled_signal;
float _feedback_value;
bool _pending_feedback;
unsigned long long _feedback_milliseconds;
static void handle_signal_connection_state_changed ( OSC::Signal *, void *o );
};

View File

@ -394,8 +394,14 @@ int signal_handler ( float value, void *user_data )
{
signal_mapping *m = (signal_mapping*)user_data;
/* DMESSAGE( "Received value: %f", value ); */
m->last_feedback_tick = buffers;
/* magic number to give a release time to prevent thrashing. */
/* if ( ! ( m->last_feedback_tick > m->last_midi_tick + 4 )) */
/* return 0; */
if ( m->is_nrpn )
{
jack_midi_event_t jev[4];
@ -916,7 +922,7 @@ void emit_signal_for_event ( const char *midi_event, midievent &e, struct nrpn_s
else if ( e.opcode() == MIDI::midievent::PITCH_WHEEL )
val = e.pitch() / (float)MAX_14BIT;
/* DMESSAGE( "Val: %f", val ); */
/* DMESSAGE( "Val: %f, sigval %f", val, m->signal->value() ); */
/* wait for values to sync for continuous controls (faders and knobs) before emitting signal. For toggles, just send it immediately. */
if (
@ -925,7 +931,7 @@ void emit_signal_for_event ( const char *midi_event, midievent &e, struct nrpn_s
&&
!m->is_toggle )
{
float percent_off = fabs( (val - m->signal->value()) * 100 );
float percent_off = fabs( val - m->signal->value() ) * 100.0f;
if ( percent_off > 5 )
{
@ -941,6 +947,9 @@ void emit_signal_for_event ( const char *midi_event, midievent &e, struct nrpn_s
}
m->last_midi_tick = buffers;
/* DMESSAGE( "Sent value: %f", val ); */
m->signal->value( val );
}

View File

@ -714,7 +714,9 @@ namespace OSC
i->second.current_value = argv[0]->f;
}
i->second.suppress_feedback = true;
/* FIXME: this was intended to break feedback cycles, but it actually
results in some feedback values not being sent at all */
/* i->second.suppress_feedback = true; */
lo_send_message(ep->_addr, dpath, msg );
return 0;

View File

@ -74,7 +74,7 @@ PROJECT="$1"
cd "$PROJECT" || fatal "No such project"
[ -f history ] && [ -f info ] || fatal "Not a Non-DAW project?"
[ -f history ] && [ -f info ] || fatal "Not a Non-Timeline project?"
[ -f .lock ] && fatal "Project appears to be in use"