diff --git a/mixer/src/Mixer.C b/mixer/src/Mixer.C index 5986066..6c6ba8c 100644 --- a/mixer/src/Mixer.C +++ b/mixer/src/Mixer.C @@ -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; } diff --git a/mixer/src/Module.C b/mixer/src/Module.C index a9e1b03..79cb2f3 100644 --- a/mixer/src/Module.C +++ b/mixer/src/Module.C @@ -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 */ diff --git a/mixer/src/Module.H b/mixer/src/Module.H index f425fa4..fd53593 100644 --- a/mixer/src/Module.H +++ b/mixer/src/Module.H @@ -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 ); }; diff --git a/mixer/src/midi-mapper.C b/mixer/src/midi-mapper.C index 2bf85ac..268c5cd 100644 --- a/mixer/src/midi-mapper.C +++ b/mixer/src/midi-mapper.C @@ -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 ); } diff --git a/nonlib/OSC/Endpoint.C b/nonlib/OSC/Endpoint.C index dc02a13..6e747c0 100644 --- a/nonlib/OSC/Endpoint.C +++ b/nonlib/OSC/Endpoint.C @@ -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; diff --git a/timeline/bin/import-external-sources b/timeline/bin/import-external-sources index 34b39eb..e821d8c 100755 --- a/timeline/bin/import-external-sources +++ b/timeline/bin/import-external-sources @@ -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"