Mixer: Make OSC ports a property of Module::Port, not Controller_Module. Therefore, all plugin parameters will be accessible via OSC.
This commit is contained in:
parent
6d7059777b
commit
f9bbdb20c9
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
#include "Engine/Engine.H"
|
#include "Engine/Engine.H"
|
||||||
#include "Chain.H"
|
#include "Chain.H"
|
||||||
|
|
||||||
#include "OSC/Endpoint.H"
|
#include "OSC/Endpoint.H"
|
||||||
|
|
||||||
// needed for mixer->endpoint
|
// needed for mixer->endpoint
|
||||||
|
@ -65,7 +64,6 @@ Controller_Module::Controller_Module ( bool is_default ) : Module( is_default, 5
|
||||||
add_port( Port( this, Port::OUTPUT, Port::CONTROL ) );
|
add_port( Port( this, Port::OUTPUT, Port::CONTROL ) );
|
||||||
|
|
||||||
_mode = GUI;
|
_mode = GUI;
|
||||||
_osc_path = NULL;
|
|
||||||
|
|
||||||
// mode( GUI );
|
// mode( GUI );
|
||||||
// mode( CV );
|
// mode( CV );
|
||||||
|
@ -86,69 +84,12 @@ Controller_Module::~Controller_Module ( )
|
||||||
|
|
||||||
/* shutdown JACK port, if we have one */
|
/* shutdown JACK port, if we have one */
|
||||||
mode( GUI );
|
mode( GUI );
|
||||||
|
|
||||||
change_osc_path( NULL );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Controller_Module::handle_chain_name_changed()
|
Controller_Module::handle_chain_name_changed()
|
||||||
{
|
{
|
||||||
change_osc_path( generate_osc_path() );
|
// change_osc_path( generate_osc_path() );
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
Controller_Module::generate_osc_path ()
|
|
||||||
{
|
|
||||||
const Port *p = control_output[0].connected_port();
|
|
||||||
|
|
||||||
if ( !p )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
// /mixer/strip/STRIPNAME/control/MODULENAME/CONTROLNAME
|
|
||||||
asprintf( &path, "/mixer/strip/%s/control/%s/%s", chain()->name(), p->module()->label(), p->name() );
|
|
||||||
|
|
||||||
// Hack to keep spaces out of OSC URL... Probably need to handle other special characters similarly.
|
|
||||||
for ( int i = strlen( path ); i--; )
|
|
||||||
{
|
|
||||||
if ( path[i] == ' ' )
|
|
||||||
path[i] = '_';
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Controller_Module::change_osc_path ( char *path )
|
|
||||||
{
|
|
||||||
if ( _osc_path )
|
|
||||||
{
|
|
||||||
mixer->osc_endpoint->del_method( _osc_path, "f" );
|
|
||||||
|
|
||||||
free( _osc_path );
|
|
||||||
free( _osc_path_cv );
|
|
||||||
|
|
||||||
_osc_path = NULL;
|
|
||||||
_osc_path_cv = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( path )
|
|
||||||
{
|
|
||||||
_osc_path_cv = (char*)malloc( strlen( path ) + 4 );
|
|
||||||
_osc_path_cv[0] = 0;
|
|
||||||
|
|
||||||
strcpy( _osc_path_cv, path );
|
|
||||||
strcat( _osc_path_cv, "/cv" );
|
|
||||||
|
|
||||||
mixer->osc_endpoint->add_method( path, "f", &Controller_Module::osc_control_change_exact, this, "value" );
|
|
||||||
|
|
||||||
mixer->osc_endpoint->add_method( _osc_path_cv, "f", &Controller_Module::osc_control_change_cv, this, "value" );
|
|
||||||
|
|
||||||
_osc_path = path;
|
|
||||||
|
|
||||||
tooltip( _osc_path );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -463,8 +404,6 @@ Controller_Module::connect_to ( Port *p )
|
||||||
}
|
}
|
||||||
|
|
||||||
// create OSC port
|
// create OSC port
|
||||||
|
|
||||||
change_osc_path( generate_osc_path() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -550,7 +489,7 @@ Controller_Module::menu ( void )
|
||||||
{ "Mode", 0, 0, 0, FL_SUBMENU },
|
{ "Mode", 0, 0, 0, FL_SUBMENU },
|
||||||
{ "Manual", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ) },
|
{ "Manual", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ) },
|
||||||
{ "Control Voltage", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ) },
|
{ "Control Voltage", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ) },
|
||||||
{ "Open Sound Control (OSC)", 0, 0, 0, FL_MENU_RADIO | ( mode() == OSC ? FL_MENU_VALUE : 0 ) },
|
// { "Open Sound Control (OSC)", 0, 0, 0, FL_MENU_RADIO | ( mode() == OSC ? FL_MENU_VALUE : 0 ) },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
|
@ -587,14 +526,20 @@ Controller_Module::handle ( int m )
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Controller_Module::handle_control_changed ( Port * )
|
Controller_Module::handle_control_changed ( Port *p )
|
||||||
{
|
{
|
||||||
/* ignore changes initiated while mouse is over widget */
|
/* ignore changes initiated while mouse is over widget */
|
||||||
if ( contains( Fl::pushed() ) )
|
if ( contains( Fl::pushed() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( p )
|
||||||
|
control_value = p->control_value();
|
||||||
|
|
||||||
if ( control->value() != control_value )
|
if ( control->value() != control_value )
|
||||||
|
{
|
||||||
redraw();
|
redraw();
|
||||||
|
DMESSAGE( "handle_control_changed" );
|
||||||
|
}
|
||||||
|
|
||||||
if ( type() == SPATIALIZATION )
|
if ( type() == SPATIALIZATION )
|
||||||
{
|
{
|
||||||
|
@ -652,64 +597,3 @@ Controller_Module::process ( nframes_t nframes )
|
||||||
control_value = f;
|
control_value = f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Controller_Module::osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
||||||
{
|
|
||||||
Controller_Module *c = (Controller_Module*)user_data;
|
|
||||||
|
|
||||||
if ( c->mode() != OSC )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OSC_DMSG();
|
|
||||||
|
|
||||||
const Port *p = c->control_output[0].connected_port();
|
|
||||||
|
|
||||||
float f = argv[0]->f;
|
|
||||||
|
|
||||||
if ( p->hints.ranged )
|
|
||||||
{
|
|
||||||
if ( f > p->hints.maximum )
|
|
||||||
f = p->hints.maximum;
|
|
||||||
else if ( f < p->hints.minimum )
|
|
||||||
f = p->hints.minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->control_value = f;
|
|
||||||
|
|
||||||
mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Controller_Module::osc_control_change_cv ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
||||||
{
|
|
||||||
Controller_Module *c = (Controller_Module*)user_data;
|
|
||||||
|
|
||||||
if ( c->mode() != OSC )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OSC_DMSG();
|
|
||||||
|
|
||||||
const Port *p = c->control_output[0].connected_port();
|
|
||||||
|
|
||||||
float f = argv[0]->f;
|
|
||||||
|
|
||||||
if (p->hints.ranged )
|
|
||||||
{
|
|
||||||
// scale value to range.
|
|
||||||
// we assume that CV values are between 0 and 1
|
|
||||||
|
|
||||||
float scale = p->hints.maximum - p->hints.minimum;
|
|
||||||
float offset = p->hints.minimum;
|
|
||||||
|
|
||||||
f = ( f * scale ) + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->control_value = f;
|
|
||||||
|
|
||||||
mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -106,9 +106,6 @@ private:
|
||||||
char *generate_osc_path ( void );
|
char *generate_osc_path ( void );
|
||||||
void change_osc_path ( char *path );
|
void change_osc_path ( char *path );
|
||||||
|
|
||||||
static int osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
|
||||||
static int osc_control_change_cv ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
|
||||||
|
|
||||||
std::vector<JACK::Port> jack_input;
|
std::vector<JACK::Port> jack_input;
|
||||||
Mode _mode;
|
Mode _mode;
|
||||||
Type _type;
|
Type _type;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <FL/Fl_Menu_Button.H>
|
#include <FL/Fl_Menu_Button.H>
|
||||||
#include "FL/test_press.H"
|
#include "FL/test_press.H"
|
||||||
#include "FL/menu_popup.H"
|
#include "FL/menu_popup.H"
|
||||||
|
#include "Mixer.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +66,6 @@ Module::Module ( ) : Fl_Group( 0, 0, 50, 50, "Unnamed" )
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
|
||||||
log_create();
|
log_create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,12 +83,16 @@ Module::~Module ( )
|
||||||
for ( unsigned int i = 0; i < audio_output.size(); ++i )
|
for ( unsigned int i = 0; i < audio_output.size(); ++i )
|
||||||
audio_output[i].disconnect();
|
audio_output[i].disconnect();
|
||||||
for ( unsigned int i = 0; i < control_input.size(); ++i )
|
for ( unsigned int i = 0; i < control_input.size(); ++i )
|
||||||
|
{
|
||||||
control_input[i].disconnect();
|
control_input[i].disconnect();
|
||||||
|
control_input[i].destroy_osc_port();
|
||||||
|
}
|
||||||
for ( unsigned int i = 0; i < control_output.size(); ++i )
|
for ( unsigned int i = 0; i < control_output.size(); ++i )
|
||||||
control_output[i].disconnect();
|
control_output[i].disconnect();
|
||||||
|
|
||||||
audio_input.clear();
|
audio_input.clear();
|
||||||
audio_output.clear();
|
audio_output.clear();
|
||||||
|
|
||||||
control_input.clear();
|
control_input.clear();
|
||||||
control_output.clear();
|
control_output.clear();
|
||||||
}
|
}
|
||||||
|
@ -187,6 +191,118 @@ Module::paste_before ( void )
|
||||||
m->copy();
|
m->copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
Module::Port::generate_osc_path ()
|
||||||
|
{
|
||||||
|
const Port *p = this;
|
||||||
|
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
// /mixer/strip/STRIPNAME/control/MODULENAME/CONTROLNAME
|
||||||
|
asprintf( &path, "/mixer/strip/%s/control/%s/%s", module()->chain()->name(), p->module()->label(), p->name() );
|
||||||
|
|
||||||
|
// asprintf( &path, "/mixer/strip/control/%s/%s", p->module()->label(), p->name() );
|
||||||
|
|
||||||
|
// Hack to keep spaces out of OSC URL... Probably need to handle other special characters similarly.
|
||||||
|
for ( int i = strlen( path ); i--; )
|
||||||
|
{
|
||||||
|
if ( path[i] == ' ' )
|
||||||
|
path[i] = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Module::Port::change_osc_path ( char *path )
|
||||||
|
{
|
||||||
|
if ( _osc_path )
|
||||||
|
{
|
||||||
|
mixer->osc_endpoint->del_method( _osc_path, "f" );
|
||||||
|
|
||||||
|
free( _osc_path );
|
||||||
|
free( _osc_path_cv );
|
||||||
|
|
||||||
|
_osc_path = NULL;
|
||||||
|
_osc_path_cv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( path )
|
||||||
|
{
|
||||||
|
_osc_path_cv = (char*)malloc( strlen( path ) + 4 );
|
||||||
|
_osc_path_cv[0] = 0;
|
||||||
|
|
||||||
|
strcpy( _osc_path_cv, path );
|
||||||
|
strcat( _osc_path_cv, "/cv" );
|
||||||
|
|
||||||
|
mixer->osc_endpoint->add_method( path, "f", &Module::Port::osc_control_change_exact, this, "value" );
|
||||||
|
|
||||||
|
mixer->osc_endpoint->add_method( _osc_path_cv, "f", &Module::Port::osc_control_change_cv, this, "value" );
|
||||||
|
|
||||||
|
_osc_path = path;
|
||||||
|
|
||||||
|
// tooltip( _osc_path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Module::Port::osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
{
|
||||||
|
Module::Port *p = (Module::Port*)user_data;
|
||||||
|
|
||||||
|
OSC_DMSG();
|
||||||
|
|
||||||
|
// const Port *p = c->control_output[0].connected_port();
|
||||||
|
|
||||||
|
float f = argv[0]->f;
|
||||||
|
|
||||||
|
if ( p->hints.ranged )
|
||||||
|
{
|
||||||
|
if ( f > p->hints.maximum )
|
||||||
|
f = p->hints.maximum;
|
||||||
|
else if ( f < p->hints.minimum )
|
||||||
|
f = p->hints.minimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->control_value( f );
|
||||||
|
|
||||||
|
mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Module::Port::osc_control_change_cv ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
{
|
||||||
|
Module::Port *p = (Module::Port*)user_data;
|
||||||
|
|
||||||
|
// const Port *p = c->control_output[0].connected_port();
|
||||||
|
|
||||||
|
float f = argv[0]->f;
|
||||||
|
|
||||||
|
if (p->hints.ranged )
|
||||||
|
{
|
||||||
|
// scale value to range.
|
||||||
|
// we assume that CV values are between 0 and 1
|
||||||
|
|
||||||
|
float scale = p->hints.maximum - p->hints.minimum;
|
||||||
|
float offset = p->hints.minimum;
|
||||||
|
|
||||||
|
f = ( f * scale ) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->control_value( f );
|
||||||
|
|
||||||
|
// c->control_value = f;
|
||||||
|
|
||||||
|
mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Module::set ( Log_Entry &e )
|
Module::set ( Log_Entry &e )
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "Loggable.H"
|
#include "Loggable.H"
|
||||||
#include "JACK/Port.H"
|
#include "JACK/Port.H"
|
||||||
|
#include "OSC/Endpoint.H"
|
||||||
|
|
||||||
class Chain;
|
class Chain;
|
||||||
class Module_Parameter_Editor;
|
class Module_Parameter_Editor;
|
||||||
|
@ -109,6 +110,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
static int osc_control_change_cv ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
|
||||||
Hints hints;
|
Hints hints;
|
||||||
|
|
||||||
Port ( Module *module, Direction direction, Type type, const char *name = 0 )
|
Port ( Module *module, Direction direction, Type type, const char *name = 0 )
|
||||||
|
@ -120,6 +124,8 @@ public:
|
||||||
_nframes = 0;
|
_nframes = 0;
|
||||||
_connected = 0;
|
_connected = 0;
|
||||||
_module = module;
|
_module = module;
|
||||||
|
_osc_path = 0;
|
||||||
|
_osc_path_cv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Port ( const Port& p )
|
Port ( const Port& p )
|
||||||
|
@ -132,10 +138,13 @@ public:
|
||||||
_connected = p._connected;
|
_connected = p._connected;
|
||||||
_module = p._module;
|
_module = p._module;
|
||||||
hints = p.hints;
|
hints = p.hints;
|
||||||
|
_osc_path = p._osc_path;
|
||||||
|
_osc_path_cv = p._osc_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Port ( )
|
virtual ~Port ( )
|
||||||
{
|
{
|
||||||
|
// change_osc_path( NULL );
|
||||||
// disconnect();
|
// disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +158,17 @@ public:
|
||||||
void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
|
void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
|
||||||
void *buffer ( void ) const { return _buf; }
|
void *buffer ( void ) const { return _buf; }
|
||||||
|
|
||||||
|
void update_osc_port ( )
|
||||||
|
{
|
||||||
|
if ( INPUT == _direction )
|
||||||
|
change_osc_path( generate_osc_path() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_osc_port ( )
|
||||||
|
{
|
||||||
|
change_osc_path( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
void control_value_no_callback ( float f )
|
void control_value_no_callback ( float f )
|
||||||
{
|
{
|
||||||
THREAD_ASSERT( UI );
|
THREAD_ASSERT( UI );
|
||||||
|
@ -163,6 +183,8 @@ public:
|
||||||
{
|
{
|
||||||
control_value_no_callback( f );
|
control_value_no_callback( f );
|
||||||
_module->handle_control_changed( this );
|
_module->handle_control_changed( this );
|
||||||
|
if ( connected() )
|
||||||
|
connected_port()->_module->handle_control_changed( connected_port() );
|
||||||
}
|
}
|
||||||
|
|
||||||
float control_value ( ) const
|
float control_value ( ) const
|
||||||
|
@ -208,6 +230,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
char *generate_osc_path ( void );
|
||||||
|
void change_osc_path ( char *path );
|
||||||
|
|
||||||
Port *_connected;
|
Port *_connected;
|
||||||
Type _type;
|
Type _type;
|
||||||
Direction _direction;
|
Direction _direction;
|
||||||
|
@ -215,6 +240,9 @@ public:
|
||||||
void *_buf;
|
void *_buf;
|
||||||
nframes_t _nframes;
|
nframes_t _nframes;
|
||||||
Module *_module;
|
Module *_module;
|
||||||
|
|
||||||
|
char *_osc_path;
|
||||||
|
char *_osc_path_cv;
|
||||||
};
|
};
|
||||||
|
|
||||||
void bbox ( int &X, int &Y, int &W, int &H )
|
void bbox ( int &X, int &Y, int &W, int &H )
|
||||||
|
@ -317,7 +345,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Chain *chain ( void ) const { return _chain; }
|
Chain *chain ( void ) const { return _chain; }
|
||||||
void chain ( Chain * v ) { _chain = v; }
|
void chain ( Chain * v )
|
||||||
|
{
|
||||||
|
_chain = v;
|
||||||
|
|
||||||
|
for ( int i = 0; i < ncontrol_inputs(); ++i )
|
||||||
|
{
|
||||||
|
control_input[i].update_osc_port();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *get_parameters ( void ) const;
|
char *get_parameters ( void ) const;
|
||||||
void set_parameters ( const char * );
|
void set_parameters ( const char * );
|
||||||
|
|
Loading…
Reference in New Issue