Browse Source

Mixer: Make OSC ports a property of Module::Port, not Controller_Module. Therefore, all plugin parameters will be accessible via OSC.

tags/non-daw-v1.1.0
Jonathan Moore Liles 13 years ago
parent
commit
f9bbdb20c9
4 changed files with 164 additions and 131 deletions
  1. +9
    -125
      mixer/src/Controller_Module.C
  2. +0
    -3
      mixer/src/Controller_Module.H
  3. +117
    -1
      mixer/src/Module.C
  4. +38
    -2
      mixer/src/Module.H

+ 9
- 125
mixer/src/Controller_Module.C View File

@@ -41,7 +41,6 @@

#include "Engine/Engine.H"
#include "Chain.H"

#include "OSC/Endpoint.H"

// 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 ) );

_mode = GUI;
_osc_path = NULL;

// mode( GUI );
// mode( CV );
@@ -86,69 +84,12 @@ Controller_Module::~Controller_Module ( )

/* shutdown JACK port, if we have one */
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;

// /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 );
}
// change_osc_path( generate_osc_path() );
}

@@ -463,8 +404,6 @@ Controller_Module::connect_to ( Port *p )
}

// create OSC port

change_osc_path( generate_osc_path() );
}

void
@@ -550,7 +489,7 @@ Controller_Module::menu ( void )
{ "Mode", 0, 0, 0, FL_SUBMENU },
{ "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 ) },
{ "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 },
};
@@ -587,14 +526,20 @@ Controller_Module::handle ( int m )
}

void
Controller_Module::handle_control_changed ( Port * )
Controller_Module::handle_control_changed ( Port *p )
{
/* ignore changes initiated while mouse is over widget */
if ( contains( Fl::pushed() ) )
return;

if ( p )
control_value = p->control_value();

if ( control->value() != control_value )
{
redraw();
DMESSAGE( "handle_control_changed" );
}

if ( type() == SPATIALIZATION )
{
@@ -652,64 +597,3 @@ Controller_Module::process ( nframes_t nframes )
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;
}

+ 0
- 3
mixer/src/Controller_Module.H View File

@@ -106,9 +106,6 @@ private:
char *generate_osc_path ( void );
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;
Mode _mode;
Type _type;


+ 117
- 1
mixer/src/Module.C View File

@@ -37,6 +37,7 @@
#include <FL/Fl_Menu_Button.H>
#include "FL/test_press.H"
#include "FL/menu_popup.H"
#include "Mixer.H"


@@ -65,7 +66,6 @@ Module::Module ( ) : Fl_Group( 0, 0, 50, 50, "Unnamed" )
{
init();


log_create();
}

@@ -83,12 +83,16 @@ Module::~Module ( )
for ( unsigned int i = 0; i < audio_output.size(); ++i )
audio_output[i].disconnect();
for ( unsigned int i = 0; i < control_input.size(); ++i )
{
control_input[i].disconnect();
control_input[i].destroy_osc_port();
}
for ( unsigned int i = 0; i < control_output.size(); ++i )
control_output[i].disconnect();

audio_input.clear();
audio_output.clear();

control_input.clear();
control_output.clear();
}
@@ -187,6 +191,118 @@ Module::paste_before ( void )
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
Module::set ( Log_Entry &e )
{


+ 38
- 2
mixer/src/Module.H View File

@@ -30,6 +30,7 @@

#include "Loggable.H"
#include "JACK/Port.H"
#include "OSC/Endpoint.H"

class Chain;
class Module_Parameter_Editor;
@@ -97,7 +98,7 @@ public:
float maximum;
float default_value;
int dimensions;
Hints ( )
{
type = LINEAR;
@@ -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;

Port ( Module *module, Direction direction, Type type, const char *name = 0 )
@@ -120,6 +124,8 @@ public:
_nframes = 0;
_connected = 0;
_module = module;
_osc_path = 0;
_osc_path_cv = 0;
}

Port ( const Port& p )
@@ -132,10 +138,13 @@ public:
_connected = p._connected;
_module = p._module;
hints = p.hints;
_osc_path = p._osc_path;
_osc_path_cv = p._osc_path;
}

virtual ~Port ( )
{
// change_osc_path( NULL );
// disconnect();
}

@@ -149,6 +158,17 @@ public:
void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
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 )
{
THREAD_ASSERT( UI );
@@ -163,6 +183,8 @@ public:
{
control_value_no_callback( f );
_module->handle_control_changed( this );
if ( connected() )
connected_port()->_module->handle_control_changed( connected_port() );
}

float control_value ( ) const
@@ -208,6 +230,9 @@ public:

private:

char *generate_osc_path ( void );
void change_osc_path ( char *path );
Port *_connected;
Type _type;
Direction _direction;
@@ -215,6 +240,9 @@ public:
void *_buf;
nframes_t _nframes;
Module *_module;

char *_osc_path;
char *_osc_path_cv;
};

void bbox ( int &X, int &Y, int &W, int &H )
@@ -317,7 +345,15 @@ public:
}

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;
void set_parameters ( const char * );


Loading…
Cancel
Save