diff --git a/veejay-ng/config.h.in b/veejay-ng/config.h.in index eac56e2d..d1a55108 100644 --- a/veejay-ng/config.h.in +++ b/veejay-ng/config.h.in @@ -87,6 +87,9 @@ /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL +/* liblo installed */ +#undef HAVE_LIBLO + /* Compiling with pthread library */ #undef HAVE_LIBPTHREAD diff --git a/veejay-ng/configure.ac b/veejay-ng/configure.ac index d7c33541..94e6013f 100644 --- a/veejay-ng/configure.ac +++ b/veejay-ng/configure.ac @@ -298,6 +298,25 @@ if test x$have_mjpegtools != xtrue ; then AC_MSG_ERROR([The MJPEGTools not found. Get it from http://mjpeg.sourceforge.net]) fi +dnl ********************************************************************* +dnl Check for liblo +dnl ********************************************************************* +have_liblo=false +PKG_CHECK_MODULES( LIBLO, [liblo >= 0.23 ], + [ + AC_SUBST( LIBLO_CFLAGS ) + AC_SUBST( LIBLO_LIBS ) + have_liblo=true + AC_DEFINE( HAVE_LIBLO, 1, [liblo installed])], + [have_liblo=false]) + +if test x$have_liblo != xtrue ; then + AC_MSG_ERROR([Liblo-0.23 (Leightweight OSC implementation) not found. Get it from http://www.ecs.soton.ac.uk/~njh/liblo/]) +fi + + + + dnl ******************************************************************** dnl Check to see if __progname is provided by the system dnl ******************************************************************** @@ -832,6 +851,7 @@ AC_MSG_NOTICE([ Required dependencies:]) AC_MSG_NOTICE([ - POSIX Threads (pthread) : ${have_pthread}]) AC_MSG_NOTICE([ - MJPEGTools : ${have_mjpegtools}]) AC_MSG_NOTICE([ - SDL Video : ${have_sdl}]) +AC_MSG_NOTICE([ - Leightweight OSC : ${have_liblo}]) AC_MSG_NOTICE([ Optional dependencies]) AC_MSG_NOTICE([ - unicap : ${have_unicap}]) AC_MSG_NOTICE([ - Jack : ${have_jack}]) diff --git a/veejay-ng/libplugger/defs.h b/veejay-ng/libplugger/defs.h index 3866c829..19d7dd4a 100644 --- a/veejay-ng/libplugger/defs.h +++ b/veejay-ng/libplugger/defs.h @@ -15,6 +15,8 @@ typedef void (*generic_default_values_f)(void *instance, void *fx_values); typedef void (*generic_push_parameter_f)(void *instance, int seq_num, void *value ); typedef void (*generic_clone_parameter_f)(void *instance, int seq_num, void *fx_values ); typedef void (*generic_reverse_clone_parameter_f)(void *instance, int seq_num, void *fxvalues ); +typedef void (*generic_reverse_clone_out_parameter_f)(void *instance, void *fxvalues ); + typedef void (*generic_deinit_f)(void *instance); typedef void (*generic_init_f)(void *instance, int w, int h ); diff --git a/veejay-ng/libplugger/livido-loader.c b/veejay-ng/libplugger/livido-loader.c index 3153dca7..bb38d12a 100644 --- a/veejay-ng/libplugger/livido-loader.c +++ b/veejay-ng/libplugger/livido-loader.c @@ -194,6 +194,69 @@ void livido_plug_parameter_set_coord( void *parameter, void *value ) vevo_property_set( parameter, "value", LIVIDO_ATOM_TYPE_DOUBLE, 2, value ); } +static int livido_pname_to_host_kind( const char *str ) +{ + if (strcasecmp( str, "NUMBER" ) == 0 ) { + return HOST_PARAM_NUMBER; + } + else if(strcasecmp(str, "INDEX" ) == 0 ) { + return HOST_PARAM_INDEX; + } + else if(strcasecmp(str, "SWITCH") == 0 ) { + return HOST_PARAM_SWITCH; + } + else if(strcasecmp(str, "COORD") == 0 ) { + return HOST_PARAM_COORD; + } + else if(strcasecmp(str, "COLOR") == 0 ) { + return HOST_PARAM_COLOR; + } + else if(strcasecmp(str, "TEXT") == 0 ) { + return HOST_PARAM_TEXT; + } + return 0; +} + +static int livido_scan_out_parameters( void *plugin , void *plugger_port) +{ + int n = 0; + int vj_np = 0; + int NP = vevo_property_num_elements( plugin , "out_parameter_templates"); + int error = 0; + + if( NP <= 0 ) + return 0; + + for( n = 0; n < NP; n ++ ) + { + char key[20]; + void *param = NULL; + + error = vevo_property_get( plugin, "out_parameter_templates", n, ¶m ); +#ifdef STRICT_CHECKING + assert( error == LIVIDO_NO_ERROR ); +#endif + + sprintf(key, "p%02d", n ); + + int ikind = 0; + char *kind = get_str_vevo( param, "kind" ); + + + ikind = livido_pname_to_host_kind(kind); + veejay_msg(0, "Parameter %d, kind '%s', type '%d'",n,kind,ikind ); + + vevo_property_set( param, "HOST_kind", VEVO_ATOM_TYPE_INT,1,&ikind ); + void *vje_port = vevo_port_new( VEVO_VJE_PORT ); + + vevo_property_set( plugger_port, key, LIVIDO_ATOM_TYPE_PORTPTR,1, &vje_port ); + + + free(kind); + } + return NP; +} + static int livido_scan_parameters( void *plugin, void *plugger_port ) { int n = 0; @@ -265,7 +328,7 @@ static int livido_scan_parameters( void *plugin, void *plugger_port ) tmp[0] = 0; tmp[1] = 1; vevo_property_set(vje_port, "min", VEVO_ATOM_TYPE_BOOL,1, &tmp[0] ); vevo_property_set(vje_port, "max", VEVO_ATOM_TYPE_BOOL,1, &tmp[1] ); - } else if (strcasecmp(kind, "COORDINATE" ) == 0 ) { + } else if (strcasecmp(kind, "COORD" ) == 0 ) { ikind = HOST_PARAM_COORD; vj_np += 2; dtmp[0] = 0.0; dtmp[1] = 0.0; vevo_property_set(vje_port, "min", VEVO_ATOM_TYPE_DOUBLE,1, &dtmp[0] ); @@ -292,7 +355,9 @@ static int livido_scan_parameters( void *plugin, void *plugger_port ) #endif } vevo_property_set( param, "HOST_kind", VEVO_ATOM_TYPE_INT,1,&ikind ); - vevo_property_set( vje_port, "HOST_kind", VEVO_ATOM_TYPE_INT,1,&ikind ); + vevo_property_set( vje_port, "HOST_kind", VEVO_ATOM_TYPE_INT,1,&ikind ); + + free(kind); } return vj_np; @@ -304,8 +369,10 @@ static int init_parameter_port(livido_port_t *ptr, livido_port_t *in_param ) int error = vevo_property_get( ptr, "HOST_kind", 0, &kind ); if( error != VEVO_NO_ERROR ) + { + veejay_msg(0, "\tProperty 'HOST_kind' not set in parameter"); return 0; - + } livido_set_parameter_f pctrl; switch(kind) @@ -324,6 +391,7 @@ static int init_parameter_port(livido_port_t *ptr, livido_port_t *in_param ) pctrl = livido_plug_parameter_set_text; break; #ifdef STRICT_CHECKING default: + veejay_msg(0, "Invalid kind : '%d'", kind ); return 0; break; #endif @@ -454,12 +522,19 @@ static int init_ports_from_template( livido_port_t *filter_instance, livido_port if( id == LIVIDO_PORT_TYPE_CHANNEL ) { if(!init_channel_port( ptr,in_channels[i],w,h)) + { + veejay_msg(0, + "Unable to intialize output channel %d ",i ); return -1; + } } else if( id == LIVIDO_PORT_TYPE_PARAMETER ) { if(!init_parameter_port( ptr, in_channels[i] )) + { + veejay_msg(0, "Unable to initialize output parameter %d", i); return -1; + } } #ifdef STRICT_CHECKING else @@ -500,8 +575,11 @@ void *livido_plug_init(void *plugin,int w, int h ) w,h, 0); if( num_in_channels < 0 ) + { + veejay_msg(0 ,"Not dealing with generator plugins yet"); return NULL; - + } + int num_out_channels = init_ports_from_template( filter_instance, filter_templ, LIVIDO_PORT_TYPE_CHANNEL, @@ -509,8 +587,10 @@ void *livido_plug_init(void *plugin,int w, int h ) w,h, 0 ); if( num_out_channels < 0 ) + { + veejay_msg(0, "Require at least 1 output channel"); return NULL; - + } int num_in_params = init_ports_from_template( filter_instance, filter_templ, LIVIDO_PORT_TYPE_PARAMETER, @@ -518,8 +598,10 @@ void *livido_plug_init(void *plugin,int w, int h ) w,h, 0 ); if( num_in_params < 0 ) + { + veejay_msg(0, "Require at least 0 input parameter"); return NULL; - + } int num_out_params = init_ports_from_template( filter_instance, filter_templ, LIVIDO_PORT_TYPE_PARAMETER, @@ -527,8 +609,11 @@ void *livido_plug_init(void *plugin,int w, int h ) w,h,0 ); if( num_out_params < 0 ) + { + veejay_msg(0, "Require at least 0 output parameters (%d)", + num_out_params); return NULL; - + } #ifdef STRICT_CHECKING assert( num_in_params >= 0 ); assert( num_out_params >= 0 ); @@ -566,6 +651,10 @@ void *livido_plug_init(void *plugin,int w, int h ) vevo_property_set( filter_instance, "HOST_plugin_param_clone_f", VEVO_ATOM_TYPE_VOIDPTR,1,&gcc ); generic_reverse_clone_parameter_f grc = livido_reverse_clone_parameter; vevo_property_set( filter_instance, "HOST_plugin_param_reverse_f", VEVO_ATOM_TYPE_VOIDPTR,1,&grc ); + generic_reverse_clone_out_parameter_f gro = livido_plug_read_output_parameters; + vevo_property_set( filter_instance, "HOST_plugin_out_param_reverse_f", VEVO_ATOM_TYPE_VOIDPTR,1,&gro ); + + generic_deinit_f gin = livido_plug_deinit; vevo_property_set( filter_instance, "HOST_plugin_deinit_f", VEVO_ATOM_TYPE_VOIDPTR,1,&gin); @@ -727,6 +816,7 @@ void livido_plug_read_output_parameters( void *instance, void *fx_values ) { int np = vevo_property_num_elements( instance, "out_parameters" ); int i; + for( i = 0; i < np ; i ++ ) { char vkey[10]; @@ -739,6 +829,8 @@ void livido_plug_read_output_parameters( void *instance, void *fx_values ) #endif sprintf(vkey, "p%02d", i ); clone_prop_vevo( param, fx_values, "value", vkey ); + + } } @@ -884,6 +976,9 @@ void* deal_with_livido( void *handle, const char *name ) #endif int n_params = livido_scan_parameters( filter_templ, port ); + + int n_oparams = livido_scan_out_parameters( filter_templ, port ); + //@ p%02d is a key with a portptr value. it contains min,max,defaults for each plugin setup() int is_mix = 0; int n_inputs = livido_property_num_elements( filter_templ, "in_channel_templates" ); @@ -899,6 +994,7 @@ void* deal_with_livido( void *handle, const char *name ) veejay_msg(0, "Livido plugin '%s'", plugin_name ); vevo_property_set( port, "num_params", VEVO_ATOM_TYPE_INT, 1, &n_params ); + vevo_property_set( port, "num_out_params", VEVO_ATOM_TYPE_INT,1,&n_oparams ); vevo_property_set( port, "name", VEVO_ATOM_TYPE_STRING,1, &clone_name ); vevo_property_set( port, "num_inputs", VEVO_ATOM_TYPE_INT,1, &n_inputs); vevo_property_set( port, "info", LIVIDO_ATOM_TYPE_PORTPTR,1,&filter_templ ); @@ -907,6 +1003,8 @@ void* deal_with_livido( void *handle, const char *name ) free(clone_name); free(plugin_name); + veejay_msg(0, "Input:%d, Output; %d", n_params, n_oparams ); + return port; } diff --git a/veejay-ng/libplugger/plugload.c b/veejay-ng/libplugger/plugload.c index 0ae4b7e6..e4d8ad9b 100644 --- a/veejay-ng/libplugger/plugload.c +++ b/veejay-ng/libplugger/plugload.c @@ -450,19 +450,13 @@ void plug_clone_from_output_parameters( void *instance, void *fx_values ) #ifdef STRICT_CHECKING assert( instance != NULL ); #endif - int type = 0; - int error = vevo_property_get( instance, "HOST_plugin_type", 0, &type); + generic_reverse_clone_out_parameter_f grc; + int error = vevo_property_get( instance, "HOST_plugin_out_param_reverse_f", 0, &grc ); #ifdef STRICT_CHECKING assert( error == VEVO_NO_ERROR ); #endif - switch( type ) - { - case VEVO_PLUG_LIVIDO: - livido_plug_read_output_parameters( instance, fx_values ); - break; - default: - break; - } + (*grc)(instance,fx_values); +/// livido_plug_read_output_parameters( instance, fx_values ); } void plug_clone_parameters( void *instance, void *fx_values ) diff --git a/veejay-ng/libvevo/vevo.c b/veejay-ng/libvevo/vevo.c index 75e4b508..d48c3a47 100644 --- a/veejay-ng/libvevo/vevo.c +++ b/veejay-ng/libvevo/vevo.c @@ -1915,6 +1915,49 @@ char *vevo_format_property( vevo_port_t *port, const char *key ) return res; } +char *vevo_format_kind( vevo_port_t *port, const char *key ) +{ + char *res = NULL; + char token[5]; + int atom_type = vevo_property_atom_type( port, key ); + + bzero(token,5); + + switch( atom_type ) + { + case VEVO_ATOM_TYPE_INT: + case VEVO_ATOM_TYPE_BOOL: + token[0] = 'd'; + break; + case VEVO_ATOM_TYPE_UINT64: + token[0] = 'D'; + break; + case VEVO_ATOM_TYPE_DOUBLE: + token[0] = 'g'; + break; + case VEVO_ATOM_TYPE_STRING: + token[0] = 's'; + break; + case VEVO_ATOM_TYPE_VOIDPTR: + token[0] = 'x'; + break; + case VEVO_ATOM_TYPE_PORTPTR: + token[0] = 'p'; + break; + default: + token[0] = 'g'; + break; + } + + if( token[0]) + { + res = strdup( token ); + } + + return res; + +} + const char *vevo_split_token_( const char *s, const char delim, char *buf, int buf_len ) { diff --git a/veejay-ng/veejay/Makefile.am b/veejay-ng/veejay/Makefile.am index 4ca29016..c8366bbf 100644 --- a/veejay-ng/veejay/Makefile.am +++ b/veejay-ng/veejay/Makefile.am @@ -19,7 +19,7 @@ INCLUDES = -I$(top_srcdir) -I$(includedir) \ -I$(top_srcdir)/libvevo \ $(FFMPEG_CFLAGS)\ ${XML_CFLAGS} ${DV_FLAGS} ${X_CFLAGS} ${XML_CPPFLAGS} \ - ${PTHREAD_CFLAGS} ${MJPEGTOOLS_CFLAGS} ${GL_CFLAGS} ${SDL_CFLAGS} + ${PTHREAD_CFLAGS} ${MJPEGTOOLS_CFLAGS} ${GL_CFLAGS} ${SDL_CFLAGS} ${LIBLO_CFLAGS} VEEJAY_LIB_FILE = libveejay.la @@ -35,6 +35,8 @@ libveejay_la_SOURCES = vj-misc.c \ gl.c vj-sdl.c \ vj-eventman.c \ vj-event.c \ + oscsend.c \ + oscservit.c \ liblavplayvj.c libveejay_la_LDFLAGS = $(VEEJAY_ALL_LIB_OPTS ) @@ -68,4 +70,4 @@ bin_PROGRAMS = $(VEEJAY_BIN) veejay_SOURCES = veejay.c veejay_LDADD = libveejay.la @LIBGETOPT_LIB@ ${FFMPEG_AVCODEC_LIBS} ${FFMPEG_AVFORMAT_LIBS} \ ${PTHREAD_LIBS} ${XML_LIBS} ${LIBDV_LIBS} ${GL_LIBS} \ - ${MJPEGTOOLS_LIBS} ${UNICAP_LIBS} ${LIBM_LIBS} ${SDL_LIBS} + ${MJPEGTOOLS_LIBS} ${UNICAP_LIBS} ${LIBM_LIBS} ${SDL_LIBS} ${LIBLO_LIBS} diff --git a/veejay-ng/veejay/liblavplayvj.c b/veejay-ng/veejay/liblavplayvj.c index cb4e755c..d3aea678 100644 --- a/veejay-ng/veejay/liblavplayvj.c +++ b/veejay-ng/veejay/liblavplayvj.c @@ -406,7 +406,7 @@ void veejay_signal_loop(void *arg) \param arg info Veejay Object \return Error Code */ -static int gl_ready_ = 0; +//static int gl_ready_ = 0; int veejay_push_results( veejay_t *info ) { sample_video_info_t *vid_info = info->video_info; @@ -424,6 +424,7 @@ int veejay_push_results( veejay_t *info ) vj_sdl_update_yuv_overlay( info->sdl_display, ref ); break; } + performer_clean_output_frame( info ); return 1; } @@ -691,6 +692,7 @@ void veejay_deinit(veejay_t *info) vj_server_shutdown(info->status_socket); vj_server_shutdown(info->command_socket); vj_server_shutdown(info->frame_socket); + veejay_free_osc_server(info->osc_server ); vj_event_stop(); samplebank_free(); plug_sys_free(); @@ -1176,6 +1178,10 @@ int vj_server_setup(veejay_t * info) if(!info->frame_socket) return 0; + const char port_str[50]; + sprintf(port_str, "%d",port ); + info->osc_server = veejay_new_osc_server( (void*)info, port_str ); + // info->mcast_socket = // vj_server_alloc(port, info->settings->vims_group_name, V_CMD ); // GoMultiCast( info->settings->group_name ); diff --git a/veejay-ng/veejay/oscsend.c b/veejay-ng/veejay/oscsend.c new file mode 100644 index 00000000..64a2327a --- /dev/null +++ b/veejay-ng/veejay/oscsend.c @@ -0,0 +1,211 @@ +/* veejay - Linux VeeJay + * (C) 2002-2006 Niels Elburg + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//@ client side implementation +#ifdef STRICT_CHECKING +#include +#endif + +typedef struct +{ + lo_address addr; + char *addr_str; + char *port_str; +} oscclient_t; + +void *veejay_new_osc_sender( const char *addr, const char *port ) +{ + oscclient_t *osc = (oscclient_t*) vj_malloc(sizeof(oscclient_t)); + osc->addr = lo_address_new( addr, port ); + + osc->addr_str = strdup( addr ); + osc->port_str = port ? strdup( port ) : NULL; + + return (void*) osc; +} + +void veejay_free_osc_sender( void *dosc ) +{ + oscclient_t *osc = (oscclient_t*) dosc; + + lo_address_free( osc->addr ); + if( osc->port_str ) + free( osc->port_str); + free(osc->addr_str); + free(osc); + osc = NULL; +} + +static void veejay_add_arguments_ ( lo_message lmsg, const char *format, va_list ap ) +{ + //http://liblo.sourceforge.net/docs/group__liblolowlevel.html#g31ac1e4c0ec6c61f665ce3f9bbdc53c3 + while( *format != 'x' ) + { + switch(*format) + { + case 'i': + lo_message_add_int32( lmsg, (int32_t) *(va_arg( ap, int*))); + break; + case 'h': + lo_message_add_int64( lmsg, (int64_t) *(va_arg( ap, int64_t*))); + break; + case 'c': + lo_message_add_string( lmsg, (char*) va_arg( ap, char*) ); + break; + case 'f': + lo_message_add_float( lmsg, (float) *(va_arg( ap, float*))); + break; + case 'd': + lo_message_add_double( lmsg, (double) *(va_arg(ap, double*))); + break; + default: +#ifdef STRICT_CHECKING + assert(0); +#endif + break; + } + *format ++; + } +} + +int veejay_send_osc( void *osc ,const char *msg, const char *format, ... ) +{ + oscclient_t *c = (oscclient_t*) osc; + lo_message lmsg = lo_message_new(); + + va_list ap; + + va_start( ap, format ); + veejay_add_arguments_( lmsg, format, ap ); + va_end(ap); + + int result = lo_send_message( c->addr, msg, lmsg ); + + lo_message_free( lmsg ); + + return result; +} + +static int _vevo_get_int( void *port, const char *key, int n_elem, lo_message lmsg ) +{ + int32_t *values = NULL; + if( n_elem == 0 ) + return VEVO_NO_ERROR; + + values = (int32_t*) vj_malloc(sizeof(int32_t) * n_elem ); + int i; + + int error; + for( i = 0; i < n_elem; i ++ ) + { + error = vevo_property_get( port, key, i, &(values[i])); +#ifdef STRICT_CHECKING + assert( error == VEVO_NO_ERROR ); +#endif + lo_message_add_int32( lmsg, values[i]); + + } + return VEVO_NO_ERROR; +} +static int _vevo_get_dbl( void *port, const char *key, int n_elem, lo_message lmsg ) +{ + double *values = NULL; + if( n_elem == 0 ) + return VEVO_NO_ERROR; + + values = (double*) vj_malloc(sizeof(double) * n_elem ); + int i; + + int error; + for( i = 0; i < n_elem; i ++ ) + { + error = vevo_property_get( port, key, i, &(values[i])); +#ifdef STRICT_CHECKING + assert( error == VEVO_NO_ERROR ); +#endif + lo_message_add_double( lmsg, values[i]); + } + return VEVO_NO_ERROR; +} + +int veejay_vevo_send_osc( void *osc, const char *msg, void *vevo_port ) +{ + char **keys = vevo_list_properties( vevo_port ); + int i; +#ifdef STRICT_CHECKING + assert( keys != NULL ); +#endif + lo_message lmsg = lo_message_new(); + oscclient_t *c = (oscclient_t*) osc; + + + for ( i = 0; keys[i] != NULL; i ++ ) + { + char *format = vevo_format_kind( vevo_port, keys[i] ); +#ifdef STRICT_CHECKING + assert( format != NULL ); +#endif + + int n_elems = vevo_property_num_elements( vevo_port, keys[i] ); + + while( *format ) + { + switch(*format) + { + case 'd': + _vevo_get_int( vevo_port, keys[i], n_elems, lmsg ); + break; + case 'g': + _vevo_get_dbl( vevo_port, keys[i], n_elems, lmsg ); + break; + default: +#ifdef STRICT_CHECKING + assert(0); +#endif + break; + } + *format++; + } + + free(keys[i]); + } + + free(keys); + + int result = lo_send_message( c->addr, msg, lmsg ); + + lo_message_free( lmsg ); + + if( result == -1) + return VEVO_ERROR_HARDWARE; //@ long live bogus error codes + + + return VEVO_NO_ERROR; +} + diff --git a/veejay-ng/veejay/oscsend.h b/veejay-ng/veejay/oscsend.h new file mode 100644 index 00000000..013f8759 --- /dev/null +++ b/veejay-ng/veejay/oscsend.h @@ -0,0 +1,25 @@ +#ifndef OSC_CLIENT_H +#define OSC_CLIENT_H +/* veejay - Linux VeeJay + * (C) 2002-2006 Niels Elburg + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +void *veejay_new_osc_sender( const char *addr, const char *port ); +void veejay_free_osc_sender( void *dosc ); +int veejay_send_osc( void *osc ,const char *msg, const char *format, ... ); +int veejay_vevo_send_osc( void *osc, const char *msg, void *vevo_port ); +#endif diff --git a/veejay-ng/veejay/oscservit.c b/veejay-ng/veejay/oscservit.c new file mode 100644 index 00000000..93db6c3b --- /dev/null +++ b/veejay-ng/veejay/oscservit.c @@ -0,0 +1,255 @@ +#ifndef OSC_SERVER_H +#define OSC_SERVER_H +/* veejay - Linux VeeJay + * (C) 2002-2006 Niels Elburg + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//@ client side implementation +#ifdef STRICT_CHECKING +#include +#endif + +#include + +typedef struct +{ + lo_server_thread st; + void *events; +} osc_recv_t; + +static struct +{ + const char *path; + int id; +} osc_paths_[] = { + { "/sample/new", VIMS_SAMPLE_NEW }, + { "/sample/select", VIMS_SAMPLE_SELECT }, + { "/sample/del", VIMS_SAMPLE_DEL }, + { "/sample/set/properties", VIMS_SAMPLE_SET_PROPERTIES }, + { "/load/samplelist", VIMS_SAMPLE_LOAD }, + { "/save/samplelist", VIMS_SAMPLE_SAVE }, + { "/sample/rec/start", VIMS_SAMPLE_START_RECORDER }, + { "/sample/rec/stop", VIMS_SAMPLE_STOP_RECORDER }, + { "/sample/rec/configure", VIMS_SAMPLE_CONFIGURE_RECORDER }, + { "/sample/set/volume", VIMS_SAMPLE_SET_VOLUME }, + { "/sample/fxc/active", VIMS_SAMPLE_CHAIN_ACTIVE }, + { "/sample/edl/paste_at", VIMS_SAMPLE_EDL_PASTE_AT }, + { "/sample/edl/copy", VIMS_SAMPLE_EDL_COPY }, + { "/sample/edl/del", VIMS_SAMPLE_EDL_DEL }, + { "/sample/edl/crop", VIMS_SAMPLE_EDL_CROP }, + { "/sample/edl/cut", VIMS_SAMPLE_EDL_CUT }, + { "/sample/edl/append", VIMS_SAMPLE_EDL_ADD }, + { "/sample/edl/export", VIMS_SAMPLE_EDL_EXPORT }, + { "/sample/edl/load", VIMS_SAMPLE_EDL_LOAD }, + { "/sample/edl/save", VIMS_SAMPLE_EDL_SAVE }, + { "/sample/chain/clear", VIMS_SAMPLE_CHAIN_CLEAR }, + { "/sample/chain/entry/select", VIMS_SAMPLE_CHAIN_SET_ENTRY }, + { "/sample/chain/entry/set", VIMS_SAMPLE_CHAIN_ENTRY_SET_FX }, + { "/sample/chain/entry/preset", VIMS_SAMPLE_CHAIN_ENTRY_SET_PRESET }, + { "/sample/chain/entry/active", VIMS_SAMPLE_CHAIN_ENTRY_SET_ACTIVE }, + { "/sample/chain/entry/value", VIMS_SAMPLE_CHAIN_ENTRY_SET_VALUE }, + { "/sample/chain/entry/channel", VIMS_SAMPLE_CHAIN_ENTRY_SET_INPUT }, + { "/sample/chain/entry/alpha", VIMS_SAMPLE_CHAIN_ENTRY_SET_ALPHA }, + { "/sample/chain/entry/clear", VIMS_SAMPLE_CHAIN_ENTRY_CLEAR }, + { "/sample/chain/entry/state", VIMS_SAMPLE_CHAIN_ENTRY_SET_STATE }, + { "/sample/chain/entry/bind", VIMS_SAMPLE_ATTACH_OUT_PARAMETER }, + { "/sample/chain/entry/release", VIMS_SAMPLE_DETACH_OUT_PARAMETER }, + { "/sample/chain/entry/register_osc_path", VIMS_SAMPLE_BIND_OUTP_OSC }, + { "/sample/chain/entry/unregister_osc_path",VIMS_SAMPLE_RELEASE_OUTP_OSC }, + { "/sample/register_osc_client", VIMS_SAMPLE_OSC_START }, + { "/sample/unregister_osc_client", VIMS_SAMPLE_OSC_STOP }, + { "/samplebank/add", VIMS_SAMPLEBANK_ADD }, + { "/samplebank/del", VIMS_SAMPLEBANK_DEL }, + { "/play", VIMS_SAMPLE_PLAY_FORWARD }, + { "/reverse", VIMS_SAMPLE_PLAY_BACKWARD }, + { "/pause", VIMS_SAMPLE_PLAY_STOP }, + { "/skip", VIMS_SAMPLE_SKIP_FRAME }, + { "/prev", VIMS_SAMPLE_PREV_FRAME }, + { "/up", VIMS_SAMPLE_SKIP_SECOND }, + { "/down", VIMS_SAMPLE_PREV_SECOND }, + { "/start", VIMS_SAMPLE_GOTO_START }, + { "/end", VIMS_SAMPLE_GOTO_END }, + { "/frame", VIMS_SAMPLE_SET_FRAME }, + { "/speed", VIMS_SAMPLE_SET_SPEED }, + { "/slow", VIMS_SAMPLE_SET_SLOW }, + + { "/fullscreen", VIMS_FULLSCREEN }, + { "/audio", VIMS_AUDIO_SET_ACTIVE }, + { "/resize", VIMS_RESIZE_SCREEN }, + + { NULL, 0 } + +}; + +void error_handler( int num, const char *msg, const char *path ) +{ + veejay_msg(0,"Liblo server error %d in path %s: %s",num,path,msg ); +} + +typedef void (*osc_event)(void *ptr, const char format[], va_list ap); + + +static char *vevo_str_to_liblo( const char *format ) +{ + int n = strlen(format); + if( n <= 0 ) + return NULL; + + char *res = (char*) malloc( n ); + int k = 0; + bzero(res,n ); + while(*format) + { + if(*format=='d' || *format=='s') + res[k++] = (*format == 'd' ? 'i' : 's'); + *format++; + } + return res; +} + +int generic_handler( const char *path, const char *types, + lo_arg **argv, int argc, void *data, void *user_data ) +{ + int vims_id = 0; + int args[16]; + double gargs[16]; + char *str[16]; + int i; + int n = 0; + int s = 0; + int g = 0; + veejay_t *info = (veejay_t*) user_data; + osc_recv_t *st = (osc_recv_t*) info->osc_server; + + int error = vevo_property_get( st->events, path,0, &vims_id ); + + memset(str, 0, sizeof(str)); + + if( vims_id == 0 || error != VEVO_NO_ERROR) + { + veejay_msg(0, "OSC path '%s' does not exist", path ); + return 0; + } + + int vims_args = vj_event_vevo_get_num_args( vims_id ); + + char *format = vj_event_vevo_get_event_format( vims_id ); + + for( i = 0; i < argc ; i ++ ) + { + switch(types[i]) + { + case 'i': + args[n++] = argv[i]->i32; + break; + + case 's': + str[s++] = strdup( (char*) &argv[i]->s ); + break; + + case 'd': + gargs[g++] = argv[i]->d; + break; + + default: + veejay_msg(0, "Skipping unknown argument type '%c' ", + types[i]); + break; + + } + } + + if( vims_args != (n + s) ) + { + char *name = vj_event_vevo_get_event_name( vims_id ); + char *loarg = vevo_str_to_liblo(format); + veejay_msg(0, "Wrong number of arguments for VIMS %d (%s)", vims_id, name); + veejay_msg(0, "FORMAT is '%s' but I received '%s'", loarg, types ); + free(name); + if(loarg) free(loarg); + } + else + { + vj_event_fire_net_event( info, + vims_id, + str[0], + args, + n + s, + 0, + gargs, + g ); + } + if(format) + free(format); + + for( i = 0; i < 16 ; i ++ ) + if( str[i] ) + free(str[i]); + + return 0; +} + + +void *veejay_new_osc_server( void *data, const char *port ) +{ + osc_recv_t *s = (osc_recv_t*) vj_malloc(sizeof( osc_recv_t)); + s->st = lo_server_thread_new( port, error_handler ); + + s->events = vevo_port_new( VEVO_ANONYMOUS_PORT ); + + int i; + for( i =0; osc_paths_[i].path != NULL ; i ++ ) + { + int error = + vevo_property_set( s->events, osc_paths_[i].path, VEVO_ATOM_TYPE_INT,1, + &(osc_paths_[i].id) ); + lo_server_thread_add_method( + s->st, + NULL, + NULL, + generic_handler, + data ); + veejay_msg(0, "Added '%s", osc_paths_[i].path ); + } + lo_server_thread_start( s->st ); + veejay_msg( 0, "OSC server ready at UDP port %d", lo_server_thread_get_port(s->st) ); + return (void*) s; +} +void veejay_free_osc_server( void *dosc ) +{ + osc_recv_t *s = (osc_recv_t*) dosc; + lo_server_thread_stop( s->st ); + vevo_port_free( s->events ); + free(s); + s = NULL; +} +#endif diff --git a/veejay-ng/veejay/oscservit.h b/veejay-ng/veejay/oscservit.h new file mode 100644 index 00000000..ecb6bfb5 --- /dev/null +++ b/veejay-ng/veejay/oscservit.h @@ -0,0 +1,23 @@ +#ifndef OSC_SERVER_H +#define OSC_SERVER_H +/* veejay - Linux VeeJay + * (C) 2002-2006 Niels Elburg + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +void *veejay_new_osc_server( void *data, const char *port ); +void veejay_free_osc_server( void *dosc ); +#endif diff --git a/veejay-ng/veejay/performer.c b/veejay-ng/veejay/performer.c index 6125a957..6f3824de 100644 --- a/veejay-ng/veejay/performer.c +++ b/veejay-ng/veejay/performer.c @@ -474,6 +474,15 @@ void *performer_get_output_frame( veejay_t *info ) // return res; } + +void performer_clean_output_frame( veejay_t *info ) +{ + performer_t *p = (performer_t*) info->performer; + memset( p->display->data[0],0,p->display->len ); + memset( p->display->data[1],128,p->display->uv_len ); + memset( p->display->data[2],128,p->display->uv_len ); +} + //! Queue sufficient audio samples for immediate playback /**! \param info Veejay Object diff --git a/veejay-ng/veejay/veejay.h b/veejay-ng/veejay/veejay.h index 2a2ca78e..e85a2e06 100644 --- a/veejay-ng/veejay/veejay.h +++ b/veejay-ng/veejay/veejay.h @@ -119,6 +119,7 @@ typedef struct void *command_socket; void *frame_socket; void *mcast_socket; + void *osc_server; int current_link; int port_offset; diff --git a/veejay-ng/veejay/vims.h b/veejay-ng/veejay/vims.h index a964c1db..9a28a98a 100644 --- a/veejay-ng/veejay/vims.h +++ b/veejay-ng/veejay/vims.h @@ -108,9 +108,15 @@ enum { VIMS_SAMPLE_CHAIN_ENTRY_SET_STATE = 377, VIMS_SAMPLE_ATTACH_OUT_PARAMETER = 378, VIMS_SAMPLE_DETACH_OUT_PARAMETER = 379, - VIMS_SAMPLE_CONFIGURE_RECORDER = 380, - VIMS_SAMPLE_START_RECORDER = 381, - VIMS_SAMPLE_STOP_RECORDER = 382, + + VIMS_SAMPLE_BIND_OUTP_OSC = 380, + VIMS_SAMPLE_RELEASE_OUTP_OSC = 381, + VIMS_SAMPLE_OSC_START = 382, + VIMS_SAMPLE_OSC_STOP = 383, + + VIMS_SAMPLE_CONFIGURE_RECORDER = 390, + VIMS_SAMPLE_START_RECORDER = 391, + VIMS_SAMPLE_STOP_RECORDER = 392, VIMS_PERFORMER_SETUP_PREVIEW = 400, VIMS_PERFORMER_GET_PREVIEW = 401, diff --git a/veejay-ng/veejay/vj-event.c b/veejay-ng/veejay/vj-event.c index b40a1b2d..0380b182 100644 --- a/veejay-ng/veejay/vj-event.c +++ b/veejay-ng/veejay/vj-event.c @@ -113,7 +113,32 @@ vj_server_send(v->frame_socket, v->current_link,str,strlen(str));\ } /* some macros for commonly used checks */ - +#define P_Ag(a,b,c,d,g)\ +{\ +int __z = 0;\ +int __y = 0;\ +unsigned char *__tmpstr = NULL;\ +if(a!=NULL){\ +unsigned int __rp;\ +unsigned int __rplen = (sizeof(a) / sizeof(int) );\ +for(__rp = 0; __rp < __rplen; __rp++) { a[__rp] = 0; g[__rp] = 0; }\ +}\ +while(*c) { \ +if( (__z+__y) > _last_known_num_args ) break; \ +switch(*c++) {\ + case 's':\ +__tmpstr = (char*)va_arg(d,char*);\ +if(__tmpstr != NULL) {\ + sprintf( b,"%s",__tmpstr);\ + }\ +__z++ ;\ + break;\ + case 'd': a[__z] = *( va_arg(d, int*)); __z++ ;\ + break; }\ + case 'g': g[__y] = *( va_arg(d, double*)); __y++;\ + break; }\ + }\ +} #define P_A(a,b,c,d)\ {\ @@ -205,7 +230,7 @@ void vj_event_print_sample_info(veejay_t *v, int id); //vj_msg_bundle *vj_event_bundle_new(char *bundle_msg, int event_id); void vj_event_trigger_function(void *ptr, vj_event f, int max_args, const char format[], ...); //void vj_event_parse_bundle(veejay_t *v, char *msg ); -void vj_event_fire_net_event(veejay_t *v, int net_id, char *str_arg, int *args, int arglen, int type); +void vj_event_fire_net_event(veejay_t *v, int net_id, char *str_arg, int *args, int arglen, int type, double *gargs, int ng); void vj_event_commit_bundle( veejay_t *v, int key_num, int key_mod); #ifdef HAVE_XML2 @@ -468,7 +493,7 @@ static int vj_event_verify_args( int *fx, int net_id , int arglen, int np, int p return 1; } -void vj_event_fire_net_event(veejay_t *v, int net_id, char *str_arg, int *args, int arglen, int prefixed) +void vj_event_fire_net_event(veejay_t *v, int net_id, char *str_arg, int *args, int iarglen, int prefixed, double *gargs, int garglen) { int np = vj_event_vevo_get_num_args(net_id); char *fmt = vj_event_vevo_get_event_format( net_id ); @@ -477,27 +502,24 @@ void vj_event_fire_net_event(veejay_t *v, int net_id, char *str_arg, int *args, vims_arg_t vims_arguments[16]; memset( vims_arguments, 0, sizeof(vims_arguments) ); - if(!vj_event_verify_args(args , net_id, arglen, np, prefixed, fmt )) - { - if(fmt) free(fmt); - return; - } - if( np == 0 ) { vj_event_vevo_inline_fire( (void*) v, net_id,NULL,NULL ); - //vj_event_vevo_inline_fire_default( (void*) v, net_id, fmt ); - //if(fmt) free(fmt); return; } int i=0; + int arglen = iarglen + garglen; while( i < arglen ) { if( fmt[fmt_offset] == 'd' ) { vims_arguments[i].value = (void*) &(args[i]); } + if( fmt[fmt_offset] == 'g' ) + { + vims_arguments[i].value = (void*) &(gargs[i]); + } if( fmt[fmt_offset] == 's' ) { if(str_arg == NULL ) @@ -567,6 +589,18 @@ void vj_event_fire_net_event(veejay_t *v, int net_id, char *str_arg, int *args, } +static int inline_str_to_dbl(const char *msg, double *val) +{ + char longest_num[16]; + int str_len = 0; + if( sscanf( msg , "%g", val ) <= 0 ) + return 0; + bzero( longest_num, 16 ); + sprintf(longest_num, "%d", *val ); + + str_len = strlen( longest_num ); + return str_len; +} static int inline_str_to_int(const char *msg, int *val) { char longest_num[16]; @@ -734,7 +768,7 @@ int vj_event_parse_msg( veejay_t * v, char *msg ) i_args[i] = vj_event_vevo_get_default_value( net_id, i ); i++; } - vj_event_fire_net_event( v, net_id, NULL, i_args, np, 0 ); + vj_event_fire_net_event( v, net_id, NULL, i_args, np, 0, NULL,0 ); } else { @@ -742,7 +776,11 @@ int vj_event_parse_msg( veejay_t * v, char *msg ) char *fmt = vj_event_vevo_get_event_format( net_id ); int flags = vj_event_vevo_get_flags( net_id ); int i = 0; + int ng = 0; + int ni = 0; + int ns = 0; int i_args[16]; + double g_args[16]; char *str = NULL; int fmt_offset = 1; char *arg_str = NULL; @@ -776,12 +814,13 @@ int vj_event_parse_msg( veejay_t * v, char *msg ) if( fmt[fmt_offset] == 'd' ) { - int il = inline_str_to_int( arguments, &i_args[i] ); + int il = inline_str_to_int( arguments, &i_args[ni] ); if( il > 0 ) { failed_arg = 0; arguments += il; } + ni ++; } if( fmt[fmt_offset] == 's' && str == NULL) { @@ -791,8 +830,18 @@ int vj_event_parse_msg( veejay_t * v, char *msg ) failed_arg = 0; arguments += strlen(str); } + ns ++; + } + if( fmt[fmt_offset] == 'g' ) + { + int il = inline_str_to_dbl( arguments, &g_args[ng]); + if( il > 0 ) + { + failed_arg = 0; + arguments += il; + } + ng ++; } - if( failed_arg ) { char *name = vj_event_vevo_get_event_name( net_id ); @@ -817,7 +866,7 @@ int vj_event_parse_msg( veejay_t * v, char *msg ) if( flags & VIMS_ALLOW_ANY ) i = np; - vj_event_fire_net_event( v, net_id, str, i_args, i, 0 ); + vj_event_fire_net_event( v, net_id, str, i_args, ni + ns, 0, g_args,ng ); if(fmt) free(fmt); @@ -1553,6 +1602,8 @@ void vj_event_chain_entry_set_input( void *ptr, const char format[], va_list ap veejay_msg(VEEJAY_MSG_ERROR, "Error setting input channel"); } } + + void vj_event_chain_entry_set_parameter_value( void *ptr, const char format[], va_list ap ) { int args[4]; @@ -1580,7 +1631,6 @@ void vj_event_chain_entry_set_parameter_value( void *ptr, const char format[], } } - void vj_event_chain_entry_set_active( void *ptr, const char format[], va_list ap ) { int args[4]; @@ -1947,3 +1997,64 @@ void vj_event_sample_stop_recorder( void *ptr, const char format[], va_list ap ) veejay_msg(2, "Stopped sample recorder. File is written"); } } + +void vj_event_sample_bind_outp_osc( void *ptr, const char format[], va_list ap ) +{ + int args[2]; + veejay_t *v = (veejay_t*) ptr; + char s[1024]; + P_A(args, s, format, ap); + + void *sample = which_sample( v, args ); + if(sample) + { + sample_add_osc_path( sample, s, args[1] ); + } + +} + +void vj_event_sample_release_outp_osc( void *ptr, const char format[], va_list ap) +{ + int args[2]; + veejay_t *v = (veejay_t*) ptr; + char *s = NULL; + P_A(args, s, format, ap); + + void *sample = which_sample( v, args ); + if(sample) + { + sample_del_osc_path( sample, args[1] ); + } +} + +void vj_event_sample_start_osc_sender( void *ptr, const char format[], va_list ap ) +{ + int args[2]; + veejay_t *v = (veejay_t*) ptr; + char s[1024]; + char port[50]; + + P_A(args, s, format, ap); + sprintf(port,"%d", args[1]); + + void *sample = which_sample( v, args ); + if(sample) + { + sample_new_osc_sender( sample, s, port ); + } +} + +void vj_event_sample_stop_osc_sender( void *ptr, const char format[], va_list ap ) +{ + int args[2]; + veejay_t *v = (veejay_t*) ptr; + char *s = NULL; + P_A(args, s, format, ap); + + void *sample = which_sample( v, args ); + if(sample) + { + sample_close_osc_sender( sample ); + } +} + diff --git a/veejay-ng/veejay/vj-event.h b/veejay-ng/veejay/vj-event.h index 530428e0..bd424167 100644 --- a/veejay-ng/veejay/vj-event.h +++ b/veejay-ng/veejay/vj-event.h @@ -69,32 +69,30 @@ void vj_event_sample_new ( void *ptr, const char format[], va_list ap ); void vj_event_quit ( void *ptr, const char format[], va_list ap ); void vj_event_set_volume ( void *ptr, const char format[], va_list ap ); void vj_event_debug_level ( void *ptr, const char format[], va_list ap ); - void vj_event_bezerk ( void *ptr, const char format[], va_list ap ); -void vj_event_fullscreen ( void *ptr, const char format[], va_list ap ); - -void vj_event_chain_entry_set_active( void *ptr, const char format[], va_list ap ); -void vj_event_chain_entry_set(void *ptr, const char format[], va_list ap); -void vj_event_chain_entry_clear( void *ptr, const char format[], va_list ap ); -void vj_event_chain_entry_set_parameter_value( void *ptr, const char format[], va_list ap ); -void vj_event_chain_entry_set_input( void *ptr, const char format[], va_list ap ); -void vj_event_chain_entry_set_alpha( void *ptr, const char format[], va_list ap); - -void vj_event_sample_attach_out_parameter( void *ptr, const char format[], va_list ap ); -void vj_event_sample_detach_out_parameter( void *ptr, const char format[], va_list ap ); - -void vj_event_sample_configure_recorder( void *ptr, const char format[], va_list ap ); -void vj_event_sample_start_recorder( void *ptr, const char format[], va_list ap ); -void vj_event_sample_stop_recorder( void *ptr, const char format[], va_list ap ); - -void vj_event_performer_configure_preview( void *ptr, const char format[], va_list ap); -void vj_event_performer_get_preview_image( void *ptr, const char format[], va_list ap); - -void vj_event_samplebank_list( void *ptr, const char format[], va_list ap ); -void vj_event_samplebank_add ( void *ptr, const char format[], va_list ap ); -void vj_event_samplebank_del ( void *ptr, const char format[], va_list ap ); -void vj_event_fx_list ( void *ptr, const char format[], va_list ap ); -void vj_event_fx_info ( void *ptr, const char format[], va_list ap ); -void vj_event_sample_fx_details(void *ptr, const char format[], va_list ap); -void vj_event_sample_fx_chain( void *ptr, const char format[], va_list ap); +void vj_event_fullscreen ( void *ptr, const char format[], va_list ap ); +void vj_event_chain_entry_set_active ( void *ptr, const char format[], va_list ap ); +void vj_event_chain_entry_set ( void *ptr, const char format[], va_list ap ); +void vj_event_chain_entry_clear ( void *ptr, const char format[], va_list ap ); +void vj_event_chain_entry_set_parameter_value( void *ptr, const char format[], va_list ap ); +void vj_event_chain_entry_set_input ( void *ptr, const char format[], va_list ap ); +void vj_event_chain_entry_set_alpha ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_attach_out_parameter ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_detach_out_parameter ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_configure_recorder ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_start_recorder ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_stop_recorder ( void *ptr, const char format[], va_list ap ); +void vj_event_performer_configure_preview ( void *ptr, const char format[], va_list ap ); +void vj_event_performer_get_preview_image ( void *ptr, const char format[], va_list ap ); +void vj_event_samplebank_list ( void *ptr, const char format[], va_list ap ); +void vj_event_samplebank_add ( void *ptr, const char format[], va_list ap ); +void vj_event_samplebank_del ( void *ptr, const char format[], va_list ap ); +void vj_event_fx_list ( void *ptr, const char format[], va_list ap ); +void vj_event_fx_info ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_fx_details ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_fx_chain ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_bind_outp_osc ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_release_outp_osc ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_start_osc_sender ( void *ptr, const char format[], va_list ap ); +void vj_event_sample_stop_osc_sender ( void *ptr, const char format[], va_list ap ); #endif diff --git a/veejay-ng/veejay/vj-eventman.c b/veejay-ng/veejay/vj-eventman.c index 12e8bcc8..8cacc6ff 100644 --- a/veejay-ng/veejay/vj-eventman.c +++ b/veejay-ng/veejay/vj-eventman.c @@ -55,6 +55,7 @@ char *vj_event_vevo_help_vims( int id, int n ); int vj_event_vevo_get_default_value(int id, int p); void vj_event_vevo_free(void); + static void dump_event_stderr(vevo_port_t *event) { char *fmt = NULL; @@ -209,7 +210,6 @@ static vevo_port_t *_new_event( vevo_property_set( p, "arguments", VEVO_ATOM_TYPE_INT, 1, &n_arg ); vevo_property_set( p, "flags", VEVO_ATOM_TYPE_INT, 1, &flags ); vevo_property_set( p, "vims_id", VEVO_ATOM_TYPE_INT, 1, &vims_id ); - va_list ap; va_start(ap, flags); #ifdef STRICT_CHECKING @@ -228,7 +228,7 @@ static vevo_port_t *_new_event( sprintf(param_name, "argument_%d", n ); const char *arg = va_arg( ap, const char*); #ifdef STRICT_CHECKING - if(!arg) veejay_msg(VEEJAY_MSG_DEBUG, "\t%s - %d = '%s' of format %c (%s)",param_name, n, arg, format[it],format ); + if(!arg) veejay_msg(0, "\t%s - %d = '%s' of format %c (%s)",param_name, n, arg, format[it],format ); assert( arg != NULL ); #endif char *descr = (char*) strdup( arg ); @@ -693,6 +693,36 @@ void vj_init_vevo_events(void) -1, NULL ); + index_map_[VIMS_SAMPLE_BIND_OUTP_OSC] = _new_event( + "%d %d %s", + VIMS_SAMPLE_BIND_OUTP_OSC, + "Bind OSC path to fx output parameters", + vj_event_sample_bind_outp_osc, + 3, + VIMS_LONG_PARAMS | VIMS_REQUIRE_ALL_PARAMS, + SAMPLE_ID_HELP, + 0, + SAMPLE_FX_ENTRY_HELP, + 0, + "OSC path", + NULL, + NULL ); + + index_map_[VIMS_SAMPLE_RELEASE_OUTP_OSC] = _new_event( + "%d %d", + VIMS_SAMPLE_RELEASE_OUTP_OSC, + "Release OSC path from fx output parameters", + vj_event_sample_release_outp_osc, + 2, + VIMS_REQUIRE_ALL_PARAMS, + SAMPLE_ID_HELP, + 0, + SAMPLE_FX_ENTRY_HELP, + 0, + NULL ); + + + index_map_[VIMS_SAMPLE_ATTACH_OUT_PARAMETER] = _new_event( "%d %d %d %d %d", VIMS_SAMPLE_ATTACH_OUT_PARAMETER, @@ -712,6 +742,34 @@ void vj_init_vevo_events(void) -1, NULL ); + index_map_[VIMS_SAMPLE_OSC_START] = _new_event( + "%d %d %s", + VIMS_SAMPLE_OSC_START, + "Start new OSC sender", + vj_event_sample_start_osc_sender, + 3, + VIMS_REQUIRE_ALL_PARAMS | VIMS_LONG_PARAMS, + SAMPLE_ID_HELP, + 0, + "Port number", + 0, + "Address", + NULL, + NULL ); + + index_map_[VIMS_SAMPLE_OSC_STOP] = _new_event( + "%d", + VIMS_SAMPLE_OSC_STOP, + "Stop OSC sender", + vj_event_sample_stop_osc_sender, + 1, + VIMS_REQUIRE_ALL_PARAMS, + SAMPLE_ID_HELP, + 0, + NULL ); + + + index_map_[VIMS_PERFORMER_SETUP_PREVIEW] = _new_event( "%d %d", VIMS_PERFORMER_SETUP_PREVIEW, diff --git a/veejay-ng/vevosample/vevosample.c b/veejay-ng/vevosample/vevosample.c index 11113aba..2784cea2 100644 --- a/veejay-ng/vevosample/vevosample.c +++ b/veejay-ng/vevosample/vevosample.c @@ -129,6 +129,7 @@ typedef struct int type; /* type of sample */ samplerecord_t *record; sampleinfo_t *info; + void *osc; } sample_runtime_data; @@ -205,6 +206,7 @@ static struct { "fx_values", VEVO_ATOM_TYPE_PORTPTR }, /* port of p0 .. pN, containing copy of fx parameter values */ { "fx_out_values", VEVO_ATOM_TYPE_PORTPTR }, /* output parmaters, p0 ... pN */ { "fx_channels", VEVO_ATOM_TYPE_PORTPTR }, /* contains list of sample pointers to use as input channels */ + { "fx_osc", VEVO_ATOM_TYPE_STRING }, /* osc message string (output)*/ }; /** @@ -746,10 +748,12 @@ int sample_process_fx( void *sample, int fx_entry ) plug_clone_from_output_parameters( fx_instance, fx_out_values ); - sample_apply_bind( sample, port ); - + //@ send osc message if needed + sample_send_osc_path( sample, port ); + + return VEVO_NO_ERROR; } @@ -1014,7 +1018,7 @@ static void sample_new_fx_chain_entry( void *sample, int id ) #endif void *fx_values = vevo_port_new( VEVO_FX_VALUES_PORT ); void *fx_channels = vevo_port_new( VEVO_ANONYMOUS_PORT ); - void *fx_out_values = vevo_port_new( VEVO_FX_VALUES_PORT ); + void *fx_out_values = vevo_port_new( VEVO_ANONYMOUS_PORT ); error = vevo_property_set( port, "fx_values", VEVO_ATOM_TYPE_PORTPTR,1,&fx_values); #ifdef STRICT_CHECKING @@ -2403,6 +2407,11 @@ static int sample_sscanf_property( sample_runtime_data *srd ,vevo_port_t *port, char *format = vevo_format_property( port, key ); int atom = vevo_property_atom_type( port, key ); +#ifdef STRICT_CHECKING + int n_elem = vevo_property_num_elements( port , key); + assert( n_elem == 1 ); // function not OK for arrays of atoms +#endif + if( format == NULL ) return done; if(atom==-1) @@ -2951,4 +2960,93 @@ int sample_apply_bind( void *sample, void *current_entry ) return 0; } +int sample_new_osc_sender(void *sample, const char *addr, const char *port ) +{ + sample_runtime_data *srd = (sample_runtime_data*) sample; + if(srd->osc) + { + veejay_msg(0, "There is already an OSC sender active"); + return 1; + } + + void *osc_client = veejay_new_osc_sender( addr, port ); + if(!osc_client) + { + veejay_msg(0, "Unable to start OSC sender"); + return 1; + } + + srd->osc = osc_client; + + veejay_msg(VEEJAY_MSG_INFO, + "OSC address '%s' port '%s', Sender active", + addr,port ); + + return VEVO_NO_ERROR; +} + +void sample_close_osc_sender( void *sample ) +{ + sample_runtime_data *srd = (sample_runtime_data*) sample; + if(srd->osc) + { + veejay_free_osc_sender( srd->osc ); + srd->osc = NULL; + veejay_msg(VEEJAY_MSG_INFO, + "OSC sender inactive"); + } +} + +void sample_add_osc_path( void *sample, const char *path, int fx_entry_id ) +{ + sample_runtime_data *srd = (sample_runtime_data*) sample; + + //@ add osc path to entry + void *port = sample_get_fx_port_ptr( sample,fx_entry_id ); + + int error = vevo_property_set( port, "fx_osc", VEVO_ATOM_TYPE_STRING,1,&path ); +#ifdef STRICT_CHECKING + assert( error == VEVO_NO_ERROR ); +#endif +} + +void sample_del_osc_path( void *sample, int fx_entry_id ) +{ + sample_runtime_data *srd = (sample_runtime_data*) sample; + + //@ add osc path to entry + void *port = sample_get_fx_port_ptr( sample,fx_entry_id ); + + int error = vevo_property_set( srd->info_port, "fx_osc", VEVO_ATOM_TYPE_STRING,0,NULL ); +#ifdef STRICT_CHECKING + assert( error == VEVO_NO_ERROR ); +#endif +} + +void sample_send_osc_path( void *sample, void *fx_entry ) +{ + sample_runtime_data *srd = (sample_runtime_data*) sample; + + char *osc_path = get_str_vevo( fx_entry, "fx_osc" ); + if(!osc_path) + { + return; + } + + void *fx_out_values = NULL; + + int error = vevo_property_get( fx_entry, "fx_out_values",0,&fx_out_values ); +#ifdef STRICT_CHECKING + assert( error == VEVO_NO_ERROR ); +#endif + + if( osc_path ) + { + veejay_vevo_send_osc( srd->osc, + osc_path, + fx_out_values ); + + free(osc_path); + } +} diff --git a/veejay-ng/vevosample/vevosample.h b/veejay-ng/vevosample/vevosample.h index 58a4c6bf..c7fb84c3 100644 --- a/veejay-ng/vevosample/vevosample.h +++ b/veejay-ng/vevosample/vevosample.h @@ -38,100 +38,75 @@ typedef struct int type; } sample_video_info_t; -int vevo_num_devices(); -void samplebank_init(); -void samplebank_free(); -int samplebank_size(); -void sample_delete_ptr(void *info); -int sample_delete(int id); -void sample_set_property_ptr( void *ptr, const char *key, int atom_type, void *value ); -void sample_set_property( int sample_id, const char *key, int atom_type, void *value ); -void sample_get_property( int sample_id, const char *key, void *dst ); -void *sample_new( int type ); -void sample_free(int sample_id); -int sample_open( void *sample, const char *token, int extra_token, sample_video_info_t *settings ); -int sample_get_frame( void *current_sample, VJFrame *slot ); -void sample_fx_set_parameter( int id, int fx_entry, int param_id,int n, void *data ); - -void sample_fx_get_parameter( int id, int fx_enty,int param_id,int idx, void *dst ); -void sample_toggle_process_entry( void *data, int fx_entry, int v ); -int sample_fx_set_active( int id, int fx_entry, int switch_value); -int sample_fx_set_channel( int id, int fx_entry, int n_input, int channel_id ); - -int sample_get_fx_alpha( void *data, int fx_entry ); -void sample_set_fx_alpha( void *data, int fx_entry, int v ); -void sample_set_itu601( void *current_sample, int status ); - - -int sample_fx_set( void *info, int fx_entry, const int new_fx ); - -void sample_set_input_frame( void *info, int fx_entry, int seq_num, VJFrame *frame ); -void sample_process_fx_chain( void *srd ); -int sample_fx_del( int id, int fx_entry ); - -int sample_xml_load( const char *filename, void *samplebank ); -int samplebank_xml_save( const char *filename ); - -void *sample_get_fx_port( int id, int fx_entry ); -int sample_process_inplace( void *sample , int fx_entry ); - -void sample_cache_data( void *sample_id ); - -void sample_save_cache_data( void *sample ); - -int sample_fx_set_in_channel( void *info, int fx_entry, int seq_num, const int sample_id ); - - -int sample_edl_get_audio_properties( void *current_sample, int *bits, int *bps, int *num_chans, long *rate ); - -int sample_get_audio_frame( void *current_sample, void *buffer , int n); - +int vevo_num_devices(); +void samplebank_init(); +void samplebank_free(); +int samplebank_size(); +void sample_delete_ptr(void *info); +int sample_delete(int id); +void sample_set_property_ptr( void *ptr, const char *key, int atom_type, void *value ); +void sample_set_property( int sample_id, const char *key, int atom_type, void *value ); +void sample_get_property( int sample_id, const char *key, void *dst ); +void *sample_new( int type ); +void sample_free(int sample_id); +int sample_open( void *sample, const char *token, int extra_token, sample_video_info_t *settings ); +int sample_get_frame( void *current_sample, VJFrame *slot ); +void sample_fx_set_parameter( int id, int fx_entry, int param_id,int n, void *data ); +void sample_fx_get_parameter( int id, int fx_enty,int param_id,int idx, void *dst ); +void sample_toggle_process_entry( void *data, int fx_entry, int v ); +int sample_fx_set_active( int id, int fx_entry, int switch_value); +int sample_fx_set_channel( int id, int fx_entry, int n_input, int channel_id ); +int sample_get_fx_alpha( void *data, int fx_entry ); +void sample_set_fx_alpha( void *data, int fx_entry, int v ); +void sample_set_itu601( void *current_sample, int status ); +int sample_fx_set( void *info, int fx_entry, const int new_fx ); +void sample_set_input_frame( void *info, int fx_entry, int seq_num, VJFrame *frame ); +void sample_process_fx_chain( void *srd ); +int sample_fx_del( int id, int fx_entry ); +int sample_xml_load( const char *filename, void *samplebank ); +int samplebank_xml_save( const char *filename ); +void *sample_get_fx_port( int id, int fx_entry ); +int sample_process_inplace( void *sample , int fx_entry ); +void sample_cache_data( void *sample_id ); +void sample_save_cache_data( void *sample ); +int sample_fx_set_in_channel( void *info, int fx_entry, int seq_num, const int sample_id ); +int sample_edl_get_audio_properties( void *current_sample, int *bits, int *bps, int *num_chans, long *rate ); +int sample_get_audio_frame( void *current_sample, void *buffer , int n); uint64_t sample_get_start_pos( void *sample ); uint64_t sample_get_end_pos( void *sample ); int sample_get_speed( void *sample ); uint64_t sample_get_current_pos( void *sample ); int sample_get_looptype( void *sample ); int sample_has_audio( void *sample ); - int sample_valid_speed(void *sample, int new_speed); int sample_valid_pos(void *sample, uint64_t pos); - -void *sample_last(void); -void *find_sample(int id); - +void *sample_last(void); +void *find_sample(int id); const char *sample_describe_type( int type ); - -void sample_fx_chain_reset( void *sample ); -int sample_fx_chain_entry_clear(void *sample, int id ); - -int sample_sscanf_port( void *sample, const char *s ); -char *sample_sprintf_port( void *sample ); - -int sample_fx_push_in_channel( void *info, int fx_entry, int seq_num, void *frame_info ); -int sample_fx_push_out_channel(void *info, int fx_entry, int seq_num, void *frame_info ); - -int sample_scan_out_channels( void *data, int fx_entry ); -void *sample_scan_in_channels( void *data, int fx_entry ); -void *sample_get_fx_port_ptr( void *data, int fx_entry ); -void *sample_get_fx_port_channels_ptr( int id, int fx_entry ); - +void sample_fx_chain_reset( void *sample ); +int sample_fx_chain_entry_clear(void *sample, int id ); +int sample_sscanf_port( void *sample, const char *s ); +char *sample_sprintf_port( void *sample ); +int sample_fx_push_in_channel( void *info, int fx_entry, int seq_num, void *frame_info ); +int sample_fx_push_out_channel(void *info, int fx_entry, int seq_num, void *frame_info ); +int sample_scan_out_channels( void *data, int fx_entry ); +void *sample_scan_in_channels( void *data, int fx_entry ); +void *sample_get_fx_port_ptr( void *data, int fx_entry ); +void *sample_get_fx_port_channels_ptr( int id, int fx_entry ); int sample_get_key_ptr( void *sample ); +int sample_edl_delete( void *current_sample, uint64_t start, uint64_t end ); +int sample_edl_paste_from_buffer( void *current_sample, uint64_t insert_at ); +int sample_edl_cut_to_buffer( void *current_sample, uint64_t start_pos, uint64_t end_pos ); +int sample_configure_recorder( void *sample, int format, const char *filename, int nframes, sample_video_info_t *ps ); +int sample_start_recorder( void *sample, sample_video_info_t *ps ); +int sample_stop_recorder( void *sample ); +int sample_record_frame( void *sample, VJFrame *frame, uint8_t *audio_buffer, int a_len ); +char *sample_get_recorded_file( void *sample ); -int sample_edl_delete( void *current_sample, uint64_t start, uint64_t end ); - -int sample_edl_paste_from_buffer( void *current_sample, uint64_t insert_at ); - -int sample_edl_cut_to_buffer( void *current_sample, uint64_t start_pos, uint64_t end_pos ); - -int sample_configure_recorder( void *sample, int format, const char *filename, int nframes, sample_video_info_t *ps ); - -int sample_start_recorder( void *sample, sample_video_info_t *ps ); - -int sample_stop_recorder( void *sample ); - -int sample_record_frame( void *sample, VJFrame *frame, uint8_t *audio_buffer, int a_len ); - -char * sample_get_recorded_file( void *sample ); - +int sample_new_osc_sender(void *sample, const char *addr, const char *port ); +void sample_close_osc_sender( void *sample ); +void sample_add_osc_path( void *sample, const char *path, int fx_entry_id ); +void sample_del_osc_path( void *sample, int fx_entry_id ); +void sample_send_osc_path( void *sample, void *fx_entry ); #endif