Mixer: Add basic OSC control to Controller_Module.
This commit is contained in:
parent
a91bc7566f
commit
53f077ee88
|
@ -446,7 +446,9 @@ Chain::name ( const char *name )
|
||||||
_name = name;
|
_name = name;
|
||||||
|
|
||||||
for ( int i = 0; i < modules(); ++i )
|
for ( int i = 0; i < modules(); ++i )
|
||||||
|
{
|
||||||
module( i )->handle_chain_name_changed();
|
module( i )->handle_chain_name_changed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -42,6 +42,11 @@
|
||||||
#include "Engine/Engine.H"
|
#include "Engine/Engine.H"
|
||||||
#include "Chain.H"
|
#include "Chain.H"
|
||||||
|
|
||||||
|
#include "OSC/Endpoint.H"
|
||||||
|
|
||||||
|
// needed for mixer->endpoint
|
||||||
|
#include "Mixer.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const float CONTROL_UPDATE_FREQ = 0.1f;
|
const float CONTROL_UPDATE_FREQ = 0.1f;
|
||||||
|
@ -60,6 +65,7 @@ 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 );
|
||||||
|
@ -70,7 +76,6 @@ Controller_Module::Controller_Module ( bool is_default ) : Module( is_default, 5
|
||||||
Fl::add_timeout( CONTROL_UPDATE_FREQ, update_cb, this );
|
Fl::add_timeout( CONTROL_UPDATE_FREQ, update_cb, this );
|
||||||
|
|
||||||
log_create();
|
log_create();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller_Module::~Controller_Module ( )
|
Controller_Module::~Controller_Module ( )
|
||||||
|
@ -81,6 +86,59 @@ 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
|
||||||
|
Controller_Module::handle_chain_name_changed()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
asprintf( &path, "/mixer/%s/%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 );
|
||||||
|
|
||||||
|
_osc_path = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( path )
|
||||||
|
{
|
||||||
|
mixer->osc_endpoint->add_method( path, "f", &Controller_Module::osc_control_change, this );
|
||||||
|
|
||||||
|
_osc_path = path;
|
||||||
|
|
||||||
|
tooltip( _osc_path );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,7 +238,7 @@ Controller_Module::mode ( Mode m )
|
||||||
chain()->engine()->unlock();
|
chain()->engine()->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( mode() == CV && m == GUI )
|
else if ( mode() == CV && m != CV )
|
||||||
{
|
{
|
||||||
chain()->engine()->lock();
|
chain()->engine()->lock();
|
||||||
|
|
||||||
|
@ -391,6 +449,10 @@ Controller_Module::connect_to ( Port *p )
|
||||||
resizable( w );
|
resizable( w );
|
||||||
/* init_sizes(); */
|
/* init_sizes(); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create OSC port
|
||||||
|
|
||||||
|
change_osc_path( generate_osc_path() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -461,6 +523,8 @@ Controller_Module::menu_cb ( const Fl_Menu_ *m )
|
||||||
mode( GUI );
|
mode( GUI );
|
||||||
else if ( ! strcmp( picked, "Mode/Control Voltage" ) )
|
else if ( ! strcmp( picked, "Mode/Control Voltage" ) )
|
||||||
mode( CV );
|
mode( CV );
|
||||||
|
else if ( ! strcmp( picked, "Mode/Open Sound Control (OSC)" ) )
|
||||||
|
mode( OSC );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** build the context menu for this control */
|
/** build the context menu for this control */
|
||||||
|
@ -474,7 +538,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 },
|
||||||
};
|
};
|
||||||
|
@ -575,3 +639,22 @@ Controller_Module::process ( nframes_t nframes )
|
||||||
control_value = f;
|
control_value = f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Controller_Module::osc_control_change ( 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();
|
||||||
|
|
||||||
|
c->control_value = argv[0]->f;
|
||||||
|
|
||||||
|
mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" );
|
||||||
|
|
||||||
|
// OSC_REPLY_OK();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Module.H"
|
#include "Module.H"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "JACK/Port.H"
|
#include "JACK/Port.H"
|
||||||
|
#include "OSC/Endpoint.H"
|
||||||
|
|
||||||
class Fl_Menu_Button;
|
class Fl_Menu_Button;
|
||||||
class Fl_Menu_;
|
class Fl_Menu_;
|
||||||
|
@ -42,6 +43,8 @@ class Controller_Module : public Module
|
||||||
static void menu_cb ( Fl_Widget *w, void *v );
|
static void menu_cb ( Fl_Widget *w, void *v );
|
||||||
void menu_cb ( const Fl_Menu_ *m );
|
void menu_cb ( const Fl_Menu_ *m );
|
||||||
|
|
||||||
|
char *_osc_path;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Mode { GUI, CV, OSC, MIDI };
|
enum Mode { GUI, CV, OSC, MIDI };
|
||||||
|
@ -76,6 +79,7 @@ public:
|
||||||
bool connect_spatializer_to ( Module *m );
|
bool connect_spatializer_to ( Module *m );
|
||||||
|
|
||||||
void handle_control_changed ( Port *p );
|
void handle_control_changed ( Port *p );
|
||||||
|
void handle_chain_name_changed ( void );
|
||||||
|
|
||||||
LOG_CREATE_FUNC( Controller_Module );
|
LOG_CREATE_FUNC( Controller_Module );
|
||||||
|
|
||||||
|
@ -89,6 +93,8 @@ public:
|
||||||
|
|
||||||
int handle ( int m );
|
int handle ( int m );
|
||||||
|
|
||||||
|
// void set_control_value ( float f ) { control_value = f; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void get ( Log_Entry &e ) const;
|
void get ( Log_Entry &e ) const;
|
||||||
|
@ -96,6 +102,12 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
char *generate_osc_path ( void );
|
||||||
|
void change_osc_path ( char *path );
|
||||||
|
|
||||||
|
static int osc_control_change ( 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;
|
||||||
|
|
|
@ -78,6 +78,8 @@ OSC_HANDLER( quit )
|
||||||
|
|
||||||
((Mixer*)user_data)->command_quit();
|
((Mixer*)user_data)->command_quit();
|
||||||
|
|
||||||
|
OSC_REPLY_OK();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,6 +548,17 @@ Module::menu ( void ) const
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Module::handle_chain_name_changed ( )
|
||||||
|
{
|
||||||
|
// pass it along to our connected Controller_Modules, if any.
|
||||||
|
for ( int i = 0; i < ncontrol_inputs(); ++i )
|
||||||
|
{
|
||||||
|
if ( control_input[i].connected() )
|
||||||
|
control_input[i].connected_port()->module()->handle_chain_name_changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Module::handle ( int m )
|
Module::handle ( int m )
|
||||||
{
|
{
|
||||||
|
|
|
@ -341,7 +341,7 @@ public:
|
||||||
|
|
||||||
/* called whenever the name of the chain changes (usually because
|
/* called whenever the name of the chain changes (usually because
|
||||||
* the name of the mixer strip changed). */
|
* the name of the mixer strip changed). */
|
||||||
virtual void handle_chain_name_changed () {}
|
virtual void handle_chain_name_changed ();
|
||||||
|
|
||||||
virtual void handle_port_connection_change () {}
|
virtual void handle_port_connection_change () {}
|
||||||
|
|
||||||
|
|
|
@ -59,12 +59,16 @@ namespace OSC
|
||||||
void
|
void
|
||||||
Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data )
|
Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data )
|
||||||
{
|
{
|
||||||
|
DMESSAGE( "Added OSC method %s (%s)", path, typespec );
|
||||||
|
|
||||||
lo_server_add_method( _server, path, typespec, handler, user_data );
|
lo_server_add_method( _server, path, typespec, handler, user_data );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Endpoint::del_method ( const char *path, const char *typespec )
|
Endpoint::del_method ( const char *path, const char *typespec )
|
||||||
{
|
{
|
||||||
|
DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
|
||||||
|
|
||||||
lo_server_del_method( _server, path, typespec );
|
lo_server_del_method( _server, path, typespec );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue