@@ -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; | |||
} | |||
@@ -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 */ | |||
@@ -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 ); | |||
}; | |||
@@ -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 ); | |||
} | |||
@@ -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; | |||
@@ -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" | |||