Mixer: Re-transmit the minimum amount of OSC/MIDI feedback messages when strips are rearranged.

This commit is contained in:
Jonathan Moore Liles 2021-01-08 17:47:03 -08:00
parent e7c85f1a37
commit 0b23c871ee
10 changed files with 62 additions and 34 deletions

View File

@ -327,10 +327,17 @@ Chain::remove ( Controller_Module *m )
} }
void void
Chain::send_feedback ( void ) Chain::send_feedback ( bool force )
{ {
for ( int i = 0; i < modules(); i++ ) for ( int i = 0; i < modules(); i++ )
module(i)->send_feedback(); module(i)->send_feedback( force );
}
void
Chain::schedule_feedback ( void )
{
for ( int i = 0; i < modules(); i++ )
module(i)->schedule_feedback();
} }
/* remove a module from the chain. this isn't guaranteed to succeed, /* remove a module from the chain. this isn't guaranteed to succeed,

View File

@ -100,8 +100,9 @@ public:
const char *name ( void ) const { return _name; } const char *name ( void ) const { return _name; }
void name ( const char *name ); void name ( const char *name );
void send_feedback ( void ); void send_feedback ( bool force );
void schedule_feedback ( void );
int get_module_instance_number ( Module *m ); int get_module_instance_number ( Module *m );
void configure_ports ( void ); void configure_ports ( void );

View File

@ -309,7 +309,7 @@ void Mixer::cb_menu(Fl_Widget* o) {
} }
else if ( !strcmp( picked, "&Remote Control/Send State" ) ) else if ( !strcmp( picked, "&Remote Control/Send State" ) )
{ {
send_feedback(); send_feedback(true);
} }
else if ( ! strcmp( picked, "&Remote Control/Clear All Mappings" ) ) else if ( ! strcmp( picked, "&Remote Control/Clear All Mappings" ) )
{ {
@ -804,6 +804,7 @@ Mixer::insert ( Mixer_Strip *ms, Mixer_Strip *before )
// mixer_strips->remove( ms ); // mixer_strips->remove( ms );
mixer_strips->insert( *ms, before ); mixer_strips->insert( *ms, before );
renumber_strips(); renumber_strips();
schedule_feedback();
// scroll->redraw(); // scroll->redraw();
} }
void void
@ -852,6 +853,7 @@ void Mixer::remove ( Mixer_Strip *ms )
parent()->redraw(); parent()->redraw();
renumber_strips(); renumber_strips();
schedule_feedback();
} }
@ -1078,21 +1080,24 @@ Mixer::send_feedback_cb ( void *v )
{ {
Mixer *m = (Mixer*)v; Mixer *m = (Mixer*)v;
m->send_feedback(); m->send_feedback(false);
/* just to it once at the start... */ /* just to it once at the start... */
Fl::repeat_timeout( FEEDBACK_UPDATE_FREQ, send_feedback_cb, v ); Fl::repeat_timeout( FEEDBACK_UPDATE_FREQ, send_feedback_cb, v );
} }
/** unconditionally send feedback to all mapped controls. This is
* useful for updating the state of an external controller. */
void void
Mixer::send_feedback ( void ) Mixer::send_feedback ( bool force )
{ {
for ( int i = 0; i < mixer_strips->children(); i++ ) for ( int i = 0; i < mixer_strips->children(); i++ )
{ ((Mixer_Strip*)mixer_strips->child(i))->send_feedback(force);
((Mixer_Strip*)mixer_strips->child(i))->send_feedback(); }
}
void
Mixer::schedule_feedback ( void )
{
for ( int i = 0; i < mixer_strips->children(); i++ )
((Mixer_Strip*)mixer_strips->child(i))->schedule_feedback();
} }

View File

@ -78,7 +78,8 @@ private:
void load_translations ( void ); void load_translations ( void );
static void send_feedback_cb ( void *v ); static void send_feedback_cb ( void *v );
void send_feedback ( void ); void send_feedback ( bool force );
void schedule_feedback ( void );
void redraw_windows ( void ); void redraw_windows ( void );
static void handle_dirty ( int, void *v ); static void handle_dirty ( int, void *v );

View File

@ -1279,10 +1279,17 @@ Mixer_Strip::handle ( int m )
} }
void void
Mixer_Strip::send_feedback ( void ) Mixer_Strip::send_feedback ( bool force )
{ {
if ( _chain ) if ( _chain )
_chain->send_feedback(); _chain->send_feedback(force);
}
void
Mixer_Strip::schedule_feedback ( void )
{
if ( _chain )
_chain->schedule_feedback();
} }
/* called to inform the strip its number has changed. */ /* called to inform the strip its number has changed. */

View File

@ -176,7 +176,8 @@ public:
// int group ( void ) const; // int group ( void ) const;
void group ( Group * ); void group ( Group * );
void send_feedback ( void ); void send_feedback ( bool force );
void schedule_feedback ( void );
int number ( void ) const; int number ( void ) const;
void number ( int ); void number ( int );
static bool import_strip ( const char *filename ); static bool import_strip ( const char *filename );

View File

@ -169,7 +169,6 @@ Module::init ( void )
_chain = 0; _chain = 0;
_instances = 1; _instances = 1;
_bypass = 0; _bypass = 0;
_pending_feedback = false;
_base_label = NULL; _base_label = NULL;
_number = -2; /* magic number indicates old instance, before numbering */ _number = -2; /* magic number indicates old instance, before numbering */
@ -371,7 +370,7 @@ Module::Port::osc_number_path ( void )
void void
Module::Port::send_feedback ( bool force ) Module::Port::send_feedback ( bool force )
{ {
if ( !_pending_feedback ) if ( !force && !_pending_feedback )
return; return;
float f = control_value(); float f = control_value();
@ -403,18 +402,17 @@ Module::Port::send_feedback ( bool force )
if ( _scaled_signal ) if ( _scaled_signal )
{ {
/* if ( fabsf( _feedback_value - f ) > (1.0f / 128.0f) ) */
if ( fabsf( _feedback_value - f ) > (1.0f / 128.0f) )
{ {
/* only send feedback if value has changed significantly since the last time we sent it. */ /* 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 ); */ /* DMESSAGE( "signal value: %f, controL_value: %f", _scaled_signal->value(), f ); */
/* send feedback for by_name signal */ /* send feedback for by_name signal */
mixer->osc_endpoint->send_feedback( _scaled_signal->path(), f ); mixer->osc_endpoint->send_feedback( _scaled_signal->path(), f, force );
/* send feedback for by number signal */ /* send feedback for by number signal */
mixer->osc_endpoint->send_feedback( osc_number_path(), f ); mixer->osc_endpoint->send_feedback( osc_number_path(), f, force );
_feedback_value = f; /* _feedback_value = f; */
_pending_feedback = false; _pending_feedback = false;
/* _scaled_signal->value( f ); */ /* _scaled_signal->value( f ); */
@ -423,10 +421,17 @@ Module::Port::send_feedback ( bool force )
} }
void void
Module::send_feedback ( void ) Module::schedule_feedback ( void )
{ {
for ( int i = 0; i < ncontrol_inputs(); i++ ) for ( int i = 0; i < ncontrol_inputs(); i++ )
control_input[i].send_feedback(true); control_input[i].schedule_feedback();
}
void
Module::send_feedback ( bool force )
{
for ( int i = 0; i < ncontrol_inputs(); i++ )
control_input[i].send_feedback(force);
} }
void void

View File

@ -48,7 +48,6 @@ class Module : public Fl_Group, public Loggable {
int _instances; int _instances;
Chain *_chain; Chain *_chain;
bool _is_default; bool _is_default;
bool _pending_feedback;
char *_base_label; char *_base_label;
nframes_t _nframes; nframes_t _nframes;
@ -165,7 +164,7 @@ public:
_by_number_path = 0; _by_number_path = 0;
_by_number_number = -1; _by_number_number = -1;
_jack_port = 0; _jack_port = 0;
_feedback_value = -2; /* _feedback_value = -2; */
_pending_feedback = false; _pending_feedback = false;
_feedback_milliseconds = 0; _feedback_milliseconds = 0;
} }
@ -184,7 +183,7 @@ public:
_by_number_path = 0; _by_number_path = 0;
_by_number_number = -1; _by_number_number = -1;
_jack_port = p._jack_port; _jack_port = p._jack_port;
_feedback_value = p._feedback_value; /* _feedback_value = p._feedback_value; */
} }
virtual ~Port ( ) virtual ~Port ( )
@ -382,7 +381,7 @@ public:
OSC::Signal *_scaled_signal; OSC::Signal *_scaled_signal;
OSC::Signal *_unscaled_signal; OSC::Signal *_unscaled_signal;
float _feedback_value; /* float _feedback_value; */
bool _pending_feedback; bool _pending_feedback;
unsigned long long _feedback_milliseconds; unsigned long long _feedback_milliseconds;
@ -525,7 +524,8 @@ public:
bool show_analysis_window ( void ); bool show_analysis_window ( void );
void send_feedback ( void ); void send_feedback ( bool force );
void schedule_feedback ( void );
virtual bool initialize ( void ) { return true; } virtual bool initialize ( void ) { return true; }
/* for the given number of inputs, return how many outputs this /* for the given number of inputs, return how many outputs this

View File

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <unistd.h>
#include <math.h>
#include "Endpoint.H" #include "Endpoint.H"
@ -1206,7 +1207,7 @@ namespace OSC
/** if there's a translation with a destination of 'path', then send feedback for it */ /** if there's a translation with a destination of 'path', then send feedback for it */
void void
Endpoint::send_feedback ( const char *path, float v ) Endpoint::send_feedback ( const char *path, float v, bool force )
{ {
for ( std::map<std::string,TranslationDestination>::iterator i = _translations.begin(); for ( std::map<std::string,TranslationDestination>::iterator i = _translations.begin();
i != _translations.end(); i != _translations.end();
@ -1215,7 +1216,7 @@ namespace OSC
if ( path && ! strcmp( i->second.path.c_str(), path ) ) if ( path && ! strcmp( i->second.path.c_str(), path ) )
{ {
/* found it */ /* found it */
if ( !i->second.suppress_feedback && i->second.current_value != v ) if ( !i->second.suppress_feedback && ( force || fabsf(i->second.current_value - v ) > 0.001f ))
{ {
const char *spath = i->first.c_str(); const char *spath = i->first.c_str();

View File

@ -307,7 +307,7 @@ namespace OSC
public: public:
void send_feedback ( const char *path, float v ); void send_feedback ( const char *path, float v, bool force );
void learn ( const char *path, void (*callback)(void*), void *userdata ); void learn ( const char *path, void (*callback)(void*), void *userdata );
lo_address address ( void ) lo_address address ( void )