2009-12-25 01:59:39 +01:00
/*******************************************************************************/
/* Copyright (C) 2009 Jonathan Moore Liles */
/* */
/* 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; see the file COPYING. If not,write to the Free Software */
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/
# include "Module.H"
# include <FL/fl_draw.H>
2010-01-28 05:39:27 +01:00
# include <FL/fl_ask.H>
2009-12-25 01:59:39 +01:00
# include <stdlib.h>
# include <string.h>
2009-12-26 01:22:56 +01:00
# include <stdio.h>
2009-12-25 01:59:39 +01:00
# include "Module_Parameter_Editor.H"
2009-12-28 06:25:28 +01:00
# include "Chain.H"
2009-12-25 01:59:39 +01:00
2010-01-18 04:59:56 +01:00
# include "JACK_Module.H"
# include "Gain_Module.H"
# include "Mono_Pan_Module.H"
# include "Meter_Module.H"
# include "Plugin_Module.H"
2013-04-17 07:42:28 +02:00
# include "AUX_Module.H"
2013-06-27 08:49:29 +02:00
# include "Spatializer_Module.H"
2010-01-18 04:59:56 +01:00
2013-09-07 08:42:21 +02:00
# include "FL/focus_frame.H"
2010-01-28 05:39:27 +01:00
# include <FL/Fl_Menu_Button.H>
# include "FL/test_press.H"
# include "FL/menu_popup.H"
2012-02-09 07:38:34 +01:00
# include "Mixer.H"
2010-01-28 05:39:27 +01:00
2013-04-13 22:18:03 +02:00
# include "Plugin_Chooser.H"
2012-02-26 03:01:46 +01:00
# include "OSC/Endpoint.H"
2012-06-05 07:58:57 +02:00
# include "string_util.h"
2009-12-25 01:59:39 +01:00
2013-06-16 02:51:50 +02:00
nframes_t Module : : _sample_rate = 0 ;
2010-01-14 04:20:40 +01:00
Module * Module : : _copied_module_empty = 0 ;
char * Module : : _copied_module_settings = 0 ;
2009-12-28 06:25:28 +01:00
Module : : Module ( int W , int H , const char * L ) : Fl_Group ( 0 , 0 , W , H , L )
{
init ( ) ;
}
Module : : Module ( bool is_default , int W , int H , const char * L ) : Fl_Group ( 0 , 0 , W , H , L ) , Loggable ( ! is_default )
{
init ( ) ;
2013-04-15 03:45:48 +02:00
this - > is_default ( is_default ) ;
2009-12-28 06:25:28 +01:00
}
2010-02-24 16:06:11 +01:00
Module : : Module ( ) : Fl_Group ( 0 , 0 , 50 , 50 , " Unnamed " )
2009-12-28 06:25:28 +01:00
{
init ( ) ;
}
2009-12-25 01:59:39 +01:00
Module : : ~ Module ( )
{
2013-08-06 09:03:19 +02:00
/* we assume that the client for this chain is already locked */
2012-02-24 04:33:09 +01:00
2010-02-05 19:43:32 +01:00
if ( _editor )
{
delete _editor ;
_editor = NULL ;
}
2012-02-24 04:33:09 +01:00
2009-12-25 01:59:39 +01:00
for ( unsigned int i = 0 ; i < audio_input . size ( ) ; + + i )
audio_input [ i ] . disconnect ( ) ;
for ( unsigned int i = 0 ; i < audio_output . size ( ) ; + + i )
audio_output [ i ] . disconnect ( ) ;
for ( unsigned int i = 0 ; i < control_input . size ( ) ; + + i )
2012-02-09 07:38:34 +01:00
{
2012-02-20 08:45:15 +01:00
/* destroy connected Controller_Module */
if ( control_input [ i ] . connected ( ) )
{
Module * o = ( Module * ) control_input [ i ] . connected_port ( ) - > module ( ) ;
2013-04-15 03:45:48 +02:00
if ( ! o - > is_default ( ) )
{
control_input [ i ] . disconnect ( ) ;
DMESSAGE ( " Deleting connected module %s " , o - > label ( ) ) ;
delete o ;
}
else
{
control_input [ i ] . disconnect ( ) ;
}
2012-02-20 08:45:15 +01:00
}
2012-02-09 07:38:34 +01:00
control_input [ i ] . destroy_osc_port ( ) ;
}
2009-12-25 01:59:39 +01:00
for ( unsigned int i = 0 ; i < control_output . size ( ) ; + + i )
control_output [ i ] . disconnect ( ) ;
audio_input . clear ( ) ;
audio_output . clear ( ) ;
2012-02-09 07:38:34 +01:00
2009-12-25 01:59:39 +01:00
control_input . clear ( ) ;
control_output . clear ( ) ;
2012-02-20 08:45:15 +01:00
if ( parent ( ) )
parent ( ) - > remove ( this ) ;
2009-12-25 01:59:39 +01:00
}
2009-12-28 06:25:28 +01:00
2013-09-15 04:27:03 +02:00
2009-12-28 06:25:28 +01:00
void
Module : : init ( void )
{
2013-08-24 23:21:44 +02:00
// _latency = 0;
2009-12-28 06:25:28 +01:00
_is_default = false ;
_editor = 0 ;
_chain = 0 ;
_instances = 1 ;
2010-01-28 05:39:27 +01:00
_bypass = 0 ;
2010-02-01 01:25:14 +01:00
2009-12-28 06:25:28 +01:00
box ( FL_UP_BOX ) ;
labeltype ( FL_NO_LABEL ) ;
2013-04-22 08:14:52 +02:00
align ( FL_ALIGN_CENTER | FL_ALIGN_INSIDE ) ;
2010-02-01 01:25:14 +01:00
set_visible_focus ( ) ;
2013-09-08 22:59:52 +02:00
selection_color ( FL_YELLOW ) ;
2013-06-27 08:49:29 +02:00
labelsize ( 12 ) ;
2013-09-08 22:59:52 +02:00
color ( fl_rgb_color ( 122 , 190 , 200 ) ) ;
2013-09-15 04:27:03 +02:00
tooltip ( ) ;
2009-12-28 06:25:28 +01:00
}
2013-09-15 04:27:03 +02:00
void
Module : : update_tooltip ( void )
{
char * s ;
asprintf ( & s , " Left click to edit parameters; Ctrl + left click to select; right click or MENU key for menu. (info: latency: %lu) " , ( unsigned long ) get_module_latency ( ) ) ;
copy_tooltip ( s ) ;
free ( s ) ;
}
2009-12-28 06:25:28 +01:00
void
Module : : get ( Log_Entry & e ) const
{
// e.add( ":name", label() );
// e.add( ":color", (unsigned long)color());
{
char * s = get_parameters ( ) ;
if ( strlen ( s ) )
e . add ( " :parameter_values " , s ) ;
delete [ ] s ;
}
e . add ( " :is_default " , is_default ( ) ) ;
e . add ( " :chain " , chain ( ) ) ;
2010-01-14 04:20:40 +01:00
e . add ( " :active " , ! bypass ( ) ) ;
2009-12-28 06:25:28 +01:00
}
2013-08-28 08:02:36 +02:00
bool
2010-01-14 04:20:40 +01:00
Module : : copy ( void ) const
{
Module * m = clone_empty ( ) ;
if ( ! m )
{
DMESSAGE ( " Module \" %s \" doesn't support cloning " , name ( ) ) ;
2013-08-28 08:02:36 +02:00
return false ;
2010-01-14 04:20:40 +01:00
}
Log_Entry * ne = new Log_Entry ( ) ;
_copied_module_empty = m ;
{
Log_Entry e ;
get ( e ) ;
for ( int i = 0 ; i < e . size ( ) ; + + i )
{
const char * s , * v ;
e . get ( i , & s , & v ) ;
/* we don't want this module to get added to the current
chain . . . */
if ( ! ( ! strcmp ( s , " :chain " ) | |
! strcmp ( s , " :is_default " ) ) )
{
DMESSAGE ( " %s = %s " , s , v ) ;
ne - > add_raw ( s , v ) ;
}
}
}
_copied_module_settings = ne - > print ( ) ;
2013-08-28 08:02:36 +02:00
return true ;
2010-01-14 04:20:40 +01:00
}
void
Module : : paste_before ( void )
{
Module * m = _copied_module_empty ;
Log_Entry le ( _copied_module_settings ) ;
2012-07-22 01:31:55 +02:00
le . remove ( " :chain " ) ;
char * print = le . print ( ) ;
DMESSAGE ( " Pasting settings: %s " , print ) ;
free ( print ) ;
2010-01-14 04:20:40 +01:00
m - > set ( le ) ;
if ( ! chain ( ) - > insert ( this , m ) )
{
fl_alert ( " Copied module cannot be inserted at this point in the chain " ) ;
}
free ( _copied_module_settings ) ;
_copied_module_settings = NULL ;
_copied_module_empty = NULL ;
2012-07-22 01:31:55 +02:00
/* set up for another paste */
2010-01-14 04:20:40 +01:00
m - > copy ( ) ;
}
2012-02-10 09:28:37 +01:00
2013-07-09 06:53:20 +02:00
const char *
2013-06-06 01:26:36 +02:00
Module : : Port : : osc_number_path ( void )
{
int n = _module - > chain ( ) - > strip ( ) - > number ( ) ;
2013-07-09 06:53:20 +02:00
if ( _by_number_path & & n = = _by_number_number )
return _by_number_path ;
if ( _by_number_path )
free ( _by_number_path ) ;
2013-06-06 01:26:36 +02:00
char * rem ;
char * client_name ;
char * strip_name ;
if ( 3 ! = sscanf ( _scaled_signal - > path ( ) , " %a[^/]/strip/%a[^/]/%a[^ \n ] " , & client_name , & strip_name , & rem ) )
return NULL ;
free ( strip_name ) ;
char * path ;
asprintf ( & path , " %s/strip#/%i/%s " , client_name , n , rem ) ;
free ( client_name ) ;
free ( rem ) ;
2013-07-09 06:53:20 +02:00
_by_number_path = path ;
_by_number_number = n ;
2013-06-06 01:26:36 +02:00
return path ;
}
2013-06-06 00:58:52 +02:00
void
Module : : Port : : send_feedback ( void )
{
2013-06-06 01:26:36 +02:00
float f = control_value ( ) ;
2013-06-06 00:58:52 +02:00
2013-06-06 01:26:36 +02:00
if ( hints . ranged )
{
// scale value to range.
float scale = hints . maximum - hints . minimum ;
float offset = hints . minimum ;
f = ( f - offset ) / scale ;
}
if ( f > 1.0 )
f = 1.0 ;
else if ( f < 0.0 )
f = 0.0 ;
2013-06-06 00:58:52 +02:00
if ( _scaled_signal )
{
/* send feedback for by_name signal */
2013-06-06 01:26:36 +02:00
mixer - > osc_endpoint - > send_feedback ( _scaled_signal - > path ( ) , f ) ;
2013-06-06 00:58:52 +02:00
2013-07-09 06:53:20 +02:00
/* send feedback for by number signal */
mixer - > osc_endpoint - > send_feedback ( osc_number_path ( ) , f ) ;
}
2013-06-06 01:26:36 +02:00
}
2013-06-06 00:58:52 +02:00
2013-06-06 01:26:36 +02:00
void
Module : : send_feedback ( void )
{
for ( int i = 0 ; i < ncontrol_inputs ( ) ; i + + )
control_input [ i ] . send_feedback ( ) ;
2013-06-06 00:58:52 +02:00
}
2012-02-10 09:28:37 +01:00
void
Module : : handle_control_changed ( Port * p )
{
if ( _editor )
_editor - > handle_control_changed ( p ) ;
2013-06-06 00:58:52 +02:00
p - > send_feedback ( ) ;
2012-02-10 09:28:37 +01:00
}
2012-02-09 07:38:34 +01:00
2013-07-14 23:12:44 +02:00
/* bool */
/* Module::Port::connected_osc ( void ) const */
/* { */
/* if ( _scaled_signal ) */
/* return _scaled_signal->connected(); */
/* else */
/* return false; */
/* } */
2013-06-06 01:26:36 +02:00
2012-02-09 07:38:34 +01:00
char *
Module : : Port : : generate_osc_path ( )
{
const Port * p = this ;
2012-02-10 09:28:37 +01:00
char * path = NULL ;
2012-02-09 07:38:34 +01:00
2012-02-26 03:01:46 +01:00
// /strip/STRIPNAME/MODULENAME/CONTROLNAME
2012-02-09 09:19:00 +01:00
2013-04-17 04:18:02 +02:00
if ( ! p - > hints . visible )
2012-02-25 05:23:45 +01:00
{
return NULL ;
}
2012-02-09 09:19:00 +01:00
int n = module ( ) - > chain ( ) - > get_module_instance_number ( module ( ) ) ;
if ( n > 0 )
2012-02-26 03:01:46 +01:00
asprintf ( & path , " /strip/%s/%s.%i/%s " , module ( ) - > chain ( ) - > name ( ) , p - > module ( ) - > label ( ) , n , p - > name ( ) ) ;
2012-02-09 09:19:00 +01:00
else
2012-02-26 03:01:46 +01:00
asprintf ( & path , " /strip/%s/%s/%s " , module ( ) - > chain ( ) - > name ( ) , p - > module ( ) - > label ( ) , p - > name ( ) ) ;
2012-02-09 07:38:34 +01:00
2012-06-05 07:58:57 +02:00
char * s = escape_url ( path ) ;
free ( path ) ;
path = s ;
2012-02-09 07:38:34 +01:00
return path ;
}
2012-02-26 03:01:46 +01:00
void
2012-04-17 06:05:34 +02:00
Module : : Port : : handle_signal_connection_state_changed ( OSC : : Signal * , void * o )
2012-02-26 03:01:46 +01:00
{
2012-04-17 06:05:34 +02:00
( ( Module : : Port * ) o ) - > module ( ) - > redraw ( ) ;
2012-02-26 03:01:46 +01:00
}
2012-02-09 07:38:34 +01:00
void
Module : : Port : : change_osc_path ( char * path )
{
if ( path )
{
2012-02-21 09:48:13 +01:00
char * scaled_path = path ;
char * unscaled_path = NULL ;
asprintf ( & unscaled_path , " %s/unscaled " , path ) ;
2012-02-09 07:38:34 +01:00
2012-02-26 03:01:46 +01:00
if ( NULL = = _scaled_signal )
2012-02-24 12:52:57 +01:00
{
2012-02-27 03:47:07 +01:00
float scaled_default = 0.5f ;
if ( hints . ranged )
{
float scale = hints . maximum - hints . minimum ;
float offset = hints . minimum ;
scaled_default = ( hints . default_value - offset ) / scale ;
}
_scaled_signal = mixer - > osc_endpoint - > add_signal ( scaled_path ,
OSC : : Signal : : Input ,
0.0 , 1.0 , scaled_default ,
& Module : : Port : : osc_control_change_cv , this ) ;
2012-04-17 06:05:34 +02:00
_scaled_signal - > connection_state_callback ( handle_signal_connection_state_changed , this ) ;
2012-02-27 03:47:07 +01:00
_unscaled_signal = mixer - > osc_endpoint - > add_signal ( unscaled_path ,
OSC : : Signal : : Input ,
hints . minimum , hints . maximum , hints . default_value ,
& Module : : Port : : osc_control_change_exact , this ) ;
2012-02-24 12:52:57 +01:00
}
else
{
2012-02-26 03:01:46 +01:00
DMESSAGE ( " Renaming OSC signals " ) ;
2012-02-24 12:52:57 +01:00
_scaled_signal - > rename ( scaled_path ) ;
_unscaled_signal - > rename ( unscaled_path ) ;
}
2012-02-09 07:38:34 +01:00
2012-02-21 09:48:13 +01:00
free ( unscaled_path ) ;
2012-02-27 03:47:07 +01:00
/* this was path, it's ok to free because it was malloc()'d in generate_osc_path */
2012-02-21 09:48:13 +01:00
free ( scaled_path ) ;
2012-02-09 07:38:34 +01:00
}
}
int
2012-02-21 09:48:13 +01:00
Module : : Port : : osc_control_change_exact ( float v , void * user_data )
2012-02-09 07:38:34 +01:00
{
Module : : Port * p = ( Module : : Port * ) user_data ;
2012-03-14 06:41:54 +01:00
Fl : : lock ( ) ;
2012-02-21 09:48:13 +01:00
float f = v ;
2012-02-09 07:38:34 +01:00
if ( p - > hints . ranged )
{
if ( f > p - > hints . maximum )
f = p - > hints . maximum ;
else if ( f < p - > hints . minimum )
f = p - > hints . minimum ;
2013-09-10 02:28:31 +02:00
if ( Hints : : BOOLEAN = = p - > hints . type )
f = f > ( p - > hints . maximum - ( p - > hints . maximum - p - > hints . minimum ) ) * 0.5f ?
p - > hints . maximum :
p - > hints . minimum ;
2012-02-09 07:38:34 +01:00
}
2013-09-10 02:28:31 +02:00
2012-02-09 07:38:34 +01:00
p - > control_value ( f ) ;
2012-03-14 06:41:54 +01:00
Fl : : unlock ( ) ;
2012-02-21 09:48:13 +01:00
// mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, f );
2012-02-09 07:38:34 +01:00
return 0 ;
}
int
2012-02-21 09:48:13 +01:00
Module : : Port : : osc_control_change_cv ( float v , void * user_data )
2012-02-09 07:38:34 +01:00
{
Module : : Port * p = ( Module : : Port * ) user_data ;
2012-02-21 09:48:13 +01:00
float f = v ;
2012-02-09 07:38:34 +01:00
2012-03-14 06:41:54 +01:00
Fl : : lock ( ) ;
2012-02-10 09:42:58 +01:00
// clamp value to control voltage range.
if ( f > 1.0 )
f = 1.0 ;
else if ( f < 0.0 )
f = 0.0 ;
if ( p - > hints . ranged )
2012-02-09 07:38:34 +01:00
{
2013-09-10 02:28:31 +02:00
if ( Hints : : BOOLEAN = = p - > hints . type )
f = f > 0.5f ? p - > hints . maximum : p - > hints . minimum ;
2012-02-09 07:38:34 +01:00
// scale value to range.
2013-09-10 02:28:31 +02:00
2012-02-09 07:38:34 +01:00
float scale = p - > hints . maximum - p - > hints . minimum ;
float offset = p - > hints . minimum ;
f = ( f * scale ) + offset ;
}
2012-03-14 06:41:54 +01:00
2012-02-09 07:38:34 +01:00
p - > control_value ( f ) ;
2012-03-14 06:41:54 +01:00
Fl : : unlock ( ) ;
2012-02-21 09:48:13 +01:00
// mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, f );
2012-02-09 07:38:34 +01:00
return 0 ;
}
2009-12-28 06:25:28 +01:00
void
Module : : set ( Log_Entry & e )
{
for ( int i = 0 ; i < e . size ( ) ; + + i )
{
const char * s , * v ;
e . get ( i , & s , & v ) ;
2013-04-17 07:42:28 +02:00
if ( ! ( strcmp ( s , " :is_default " ) ) )
{
is_default ( atoi ( v ) ) ;
}
else if ( ! strcmp ( s , " :chain " ) )
2009-12-28 06:25:28 +01:00
{
/* This trickiness is because we may need to know the name of
2010-01-28 05:39:27 +01:00
our chain before we actually get added to it . */
2009-12-28 06:25:28 +01:00
int i ;
sscanf ( v , " %X " , & i ) ;
Chain * t = ( Chain * ) Loggable : : find ( i ) ;
assert ( t ) ;
chain ( t ) ;
}
}
for ( int i = 0 ; i < e . size ( ) ; + + i )
{
const char * s , * v ;
e . get ( i , & s , & v ) ;
/* if ( ! strcmp( s, ":name" ) ) */
/* label( v ); */
if ( ! strcmp ( s , " :parameter_values " ) )
{
set_parameters ( v ) ;
}
2010-01-13 08:14:11 +01:00
else if ( ! ( strcmp ( s , " :active " ) ) )
{
2010-01-14 04:20:40 +01:00
bypass ( ! atoi ( v ) ) ;
2010-01-13 08:14:11 +01:00
}
2009-12-28 06:25:28 +01:00
else if ( ! strcmp ( s , " :chain " ) )
{
int i ;
sscanf ( v , " %X " , & i ) ;
Chain * t = ( Chain * ) Loggable : : find ( i ) ;
assert ( t ) ;
t - > add ( this ) ;
}
}
}
2009-12-25 01:59:39 +01:00
2012-07-22 01:31:55 +02:00
void
Module : : chain ( Chain * v )
{
if ( _chain ! = v )
{
DMESSAGE ( " Adding module %s in to chain %s " , label ( ) , v ? v - > name ( ) : " NULL " ) ;
_chain = v ;
for ( int i = 0 ; i < ncontrol_inputs ( ) ; + + i )
{
control_input [ i ] . update_osc_port ( ) ;
}
}
else
{
DMESSAGE ( " Module %s already belongs to chain %s " , label ( ) , v ? v - > name ( ) : " NULL " ) ;
}
}
2009-12-26 01:22:56 +01:00
/* return a string serializing this module's parameter settings. The
format is 1.0 : 2.0 : . . . Where 1.0 is the value of the first control
input , 2.0 is the value of the second control input etc .
2009-12-28 06:25:28 +01:00
*/
2009-12-26 01:22:56 +01:00
char *
2009-12-28 06:25:28 +01:00
Module : : get_parameters ( void ) const
2009-12-26 01:22:56 +01:00
{
char * s = new char [ 1024 ] ;
s [ 0 ] = 0 ;
char * sp = s ;
if ( control_input . size ( ) )
{
2009-12-28 06:25:28 +01:00
for ( unsigned int i = 0 ; i < control_input . size ( ) ; + + i )
sp + = snprintf ( sp , 1024 - ( sp - s ) , " %f: " , control_input [ i ] . control_value ( ) ) ;
2009-12-26 01:22:56 +01:00
2009-12-28 06:25:28 +01:00
* ( sp - 1 ) = ' \0 ' ;
2009-12-26 01:22:56 +01:00
}
return s ;
}
2009-12-28 06:25:28 +01:00
void
Module : : set_parameters ( const char * parameters )
{
char * s = strdup ( parameters ) ;
char * start = s ;
2010-01-14 04:20:40 +01:00
unsigned int i = 0 ;
2009-12-28 06:25:28 +01:00
for ( char * sp = s ; ; + + sp )
{
if ( ' : ' = = * sp | | ' \0 ' = = * sp )
{
char was = * sp ;
* sp = ' \0 ' ;
DMESSAGE ( start ) ;
if ( i < control_input . size ( ) )
control_input [ i ] . control_value ( atof ( start ) ) ;
else
{
WARNING ( " Module has no parameter at index %i " , i ) ;
break ;
}
i + + ;
if ( ' \0 ' = = was )
break ;
start = sp + 1 ;
}
}
free ( s ) ;
}
2009-12-26 01:22:56 +01:00
2009-12-25 01:59:39 +01:00
void
2013-04-17 07:42:28 +02:00
Module : : draw_box ( int tx , int ty , int tw , int th )
2009-12-25 01:59:39 +01:00
{
2010-02-01 02:14:54 +01:00
fl_color ( fl_contrast ( FL_FOREGROUND_COLOR , color ( ) ) ) ;
2009-12-25 01:59:39 +01:00
fl_push_clip ( tx , ty , tw , th ) ;
2013-03-15 01:30:50 +01:00
Fl_Color c = color ( ) ;
2009-12-28 06:25:28 +01:00
2013-06-25 02:41:15 +02:00
if ( ! active_r ( ) )
c = fl_inactive ( c ) ;
2009-12-25 01:59:39 +01:00
int spacing = w ( ) / instances ( ) ;
for ( int i = instances ( ) ; i - - ; )
{
2013-03-15 01:30:50 +01:00
fl_draw_box ( box ( ) , tx + ( spacing * i ) , ty , tw / instances ( ) , th , c ) ;
2009-12-25 01:59:39 +01:00
}
2010-02-01 01:25:14 +01:00
2009-12-25 01:59:39 +01:00
if ( audio_input . size ( ) & & audio_output . size ( ) )
{
/* maybe draw control indicators */
if ( control_input . size ( ) )
2012-02-25 05:23:45 +01:00
{
2009-12-25 01:59:39 +01:00
fl_draw_box ( FL_ROUNDED_BOX , tx + 4 , ty + 4 , 5 , 5 , is_being_controlled ( ) ? FL_YELLOW : fl_inactive ( FL_YELLOW ) ) ;
2012-02-25 05:23:45 +01:00
2013-07-14 23:12:44 +02:00
/* fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + th - 8, 5, 5, is_being_controlled_osc() ? FL_YELLOW : fl_inactive( FL_YELLOW ) ); */
2012-02-25 05:23:45 +01:00
}
2009-12-25 01:59:39 +01:00
if ( control_output . size ( ) )
fl_draw_box ( FL_ROUNDED_BOX , tx + tw - 8 , ty + 4 , 5 , 5 , is_controlling ( ) ? FL_YELLOW : fl_inactive ( FL_YELLOW ) ) ;
}
2013-06-27 08:42:42 +02:00
fl_push_clip ( tx + Fl : : box_dx ( box ( ) ) , ty + Fl : : box_dy ( box ( ) ) , tw - Fl : : box_dw ( box ( ) ) , th - Fl : : box_dh ( box ( ) ) ) ;
2009-12-25 01:59:39 +01:00
Fl_Group : : draw_children ( ) ;
2010-02-06 01:38:40 +01:00
fl_pop_clip ( ) ;
2013-06-27 08:42:42 +02:00
2013-09-08 22:59:52 +02:00
if ( focused_r ( this ) )
2013-09-07 08:42:21 +02:00
draw_focus_frame ( tx , ty , tw , th , selection_color ( ) ) ;
2013-09-02 05:07:16 +02:00
2013-06-27 08:42:42 +02:00
fl_pop_clip ( ) ;
2009-12-25 01:59:39 +01:00
}
2013-10-01 04:10:17 +02:00
# include "SpectrumView.H"
# include <FL/Fl_Double_Window.H>
bool
Module : : show_analysis_window ( void )
{
2013-10-06 04:50:37 +02:00
/* use a large window for more accuracy at low frequencies */
nframes_t nframes = sample_rate ( ) / 2 ;
2013-10-01 04:10:17 +02:00
float * buf = new float [ nframes ] ;
2013-10-02 03:08:35 +02:00
memset ( buf , 0 , sizeof ( float ) * nframes ) ;
buf [ 0 ] = 1 ;
2013-10-01 04:10:17 +02:00
if ( ! get_impulse_response ( buf , nframes ) )
2013-10-02 03:08:35 +02:00
{
// return false;
}
2013-10-01 04:10:17 +02:00
Fl_Double_Window * w = new Fl_Double_Window ( 1000 , 500 ) ;
{
SpectrumView * o = new SpectrumView ( 25 , 25 , 1000 - 50 , 500 - 50 , label ( ) ) ;
o - > labelsize ( 10 ) ;
o - > align ( FL_ALIGN_RIGHT | FL_ALIGN_TOP ) ;
o - > sample_rate ( sample_rate ( ) ) ;
o - > data ( buf , nframes ) ;
}
w - > end ( ) ;
w - > show ( ) ;
while ( w - > shown ( ) )
Fl : : wait ( ) ;
2013-10-12 23:23:06 +02:00
delete w ;
2013-10-01 04:10:17 +02:00
return true ;
}
2009-12-25 01:59:39 +01:00
void
2013-04-17 07:42:28 +02:00
Module : : draw_label ( int tx , int ty , int tw , int th )
2009-12-25 01:59:39 +01:00
{
bbox ( tx , ty , tw , th ) ;
2013-08-24 02:04:25 +02:00
if ( ! label ( ) )
return ;
char * lab = strdup ( label ( ) ) ;
2009-12-25 01:59:39 +01:00
2013-09-08 22:59:52 +02:00
Fl_Color c = fl_contrast ( FL_FOREGROUND_COLOR , color ( ) ) ;
2013-06-25 02:17:15 +02:00
2013-09-08 22:59:52 +02:00
fl_color ( active_r ( ) & & ! bypass ( ) ? c : fl_inactive ( c ) ) ;
2009-12-25 01:59:39 +01:00
2013-06-27 08:49:29 +02:00
fl_font ( FL_HELVETICA , labelsize ( ) ) ;
2010-01-19 05:44:57 +01:00
2013-08-27 08:05:27 +02:00
char * di = strstr ( lab , " - " ) ;
if ( ! di )
2013-09-25 06:40:09 +02:00
di = strstr ( lab , " " ) ;
2013-08-27 08:05:27 +02:00
2013-08-24 02:04:25 +02:00
if ( di )
* di = ' \0 ' ;
2010-01-19 05:44:57 +01:00
2013-08-24 02:04:25 +02:00
int LW = fl_width ( lab ) ;
2009-12-25 01:59:39 +01:00
char * s = NULL ;
2013-08-24 02:04:25 +02:00
bool initial = true ;
2013-03-16 01:49:17 +01:00
if ( LW > tw )
2009-12-25 01:59:39 +01:00
{
2013-08-24 02:04:25 +02:00
s = new char [ strlen ( lab ) + 1 ] ;
2009-12-25 01:59:39 +01:00
char * sp = s ;
2013-08-24 02:04:25 +02:00
const char * lp = lab ;
2009-12-25 01:59:39 +01:00
for ( ; * lp ; + + lp )
2013-08-24 02:04:25 +02:00
{
bool skip = false ;
2009-12-25 01:59:39 +01:00
switch ( * lp )
{
2013-08-24 02:04:25 +02:00
case ' ' :
initial = true ;
skip = false ;
break ;
2009-12-25 01:59:39 +01:00
case ' i ' : case ' e ' : case ' o ' : case ' u ' : case ' a ' :
2013-08-24 02:04:25 +02:00
skip = ! initial ;
initial = false ;
2009-12-25 01:59:39 +01:00
break ;
default :
2013-08-24 02:04:25 +02:00
skip = false ;
initial = false ;
break ;
2009-12-25 01:59:39 +01:00
}
2013-08-24 02:04:25 +02:00
if ( ! skip )
* ( sp + + ) = * lp ;
}
2009-12-25 01:59:39 +01:00
* sp = ' \0 ' ;
2013-08-24 02:04:25 +02:00
2009-12-25 01:59:39 +01:00
}
2013-08-24 02:04:25 +02:00
fl_draw ( s ? s : lab , tx , ty , tw , th , align ( ) | FL_ALIGN_CLIP ) ;
2013-09-08 22:59:52 +02:00
if ( bypass ( ) )
{
fl_color ( fl_color_add_alpha ( fl_color ( ) , 127 ) ) ;
fl_line_style ( FL_SOLID , 2 ) ;
fl_line ( tx , ty + th * 0.5 , tx + tw , ty + th * 0.5 ) ;
fl_line_style ( FL_SOLID , 0 ) ;
}
2013-08-24 02:04:25 +02:00
free ( lab ) ;
2009-12-25 01:59:39 +01:00
if ( s )
delete [ ] s ;
}
2010-01-28 05:39:27 +01:00
void
Module : : insert_menu_cb ( const Fl_Menu_ * m )
2010-01-18 04:59:56 +01:00
{
2013-04-13 22:18:03 +02:00
2013-04-17 07:42:28 +02:00
const char * picked = m - > mvalue ( ) - > label ( ) ;
DMESSAGE ( " picked = %s " , picked ) ;
2013-04-13 22:18:03 +02:00
Module * mod = NULL ;
2013-04-17 07:42:28 +02:00
if ( ! strcmp ( picked , " Aux " ) )
2010-01-28 05:39:27 +01:00
{
2013-04-17 07:42:28 +02:00
int n = 0 ;
for ( int i = 0 ; i < chain ( ) - > modules ( ) ; i + + )
2010-01-28 05:39:27 +01:00
{
2013-04-17 07:42:28 +02:00
if ( ! strcmp ( chain ( ) - > module ( i ) - > name ( ) , " AUX " ) )
n + + ;
2010-01-28 05:39:27 +01:00
}
2013-04-17 07:42:28 +02:00
AUX_Module * jm = new AUX_Module ( ) ;
jm - > chain ( chain ( ) ) ;
jm - > number ( n ) ;
jm - > configure_inputs ( ninputs ( ) ) ;
jm - > configure_outputs ( ninputs ( ) ) ;
jm - > initialize ( ) ;
mod = jm ;
}
2013-06-27 08:49:29 +02:00
if ( ! strcmp ( picked , " Spatializer " ) )
{
int n = 0 ;
for ( int i = 0 ; i < chain ( ) - > modules ( ) ; i + + )
{
if ( ! strcmp ( chain ( ) - > module ( i ) - > name ( ) , " Spatializer " ) )
n + + ;
}
if ( n = = 0 )
{
Spatializer_Module * jm = new Spatializer_Module ( ) ;
jm - > chain ( chain ( ) ) ;
// jm->number( n );
// jm->configure_inputs( ninputs() );
// jm->configure_outputs( ninputs() );
jm - > initialize ( ) ;
mod = jm ;
}
}
2013-04-17 07:42:28 +02:00
else if ( ! strcmp ( picked , " Gain " ) )
mod = new Gain_Module ( ) ;
2013-06-27 08:49:29 +02:00
/* else if ( !strcmp( picked, "Spatializer" ) ) */
/* mod = new Spatializer_Module(); */
2013-04-17 07:42:28 +02:00
else if ( ! strcmp ( picked , " Meter " ) )
mod = new Meter_Module ( ) ;
else if ( ! strcmp ( picked , " Mono Pan " ) )
mod = new Mono_Pan_Module ( ) ;
else if ( ! strcmp ( picked , " Plugin " ) )
{
unsigned long id = Plugin_Chooser : : plugin_chooser ( this - > ninputs ( ) ) ;
if ( id = = 0 )
return ;
Plugin_Module * m = new Plugin_Module ( ) ;
m - > load ( id ) ;
mod = m ;
2013-04-13 22:18:03 +02:00
}
2010-01-18 04:59:56 +01:00
2013-04-13 22:18:03 +02:00
if ( mod )
{
if ( ! chain ( ) - > insert ( this , mod ) )
{
fl_alert ( " Cannot insert this module at this point in the chain " ) ;
delete mod ;
return ;
2010-01-28 05:39:27 +01:00
}
2013-04-13 22:18:03 +02:00
redraw ( ) ;
2010-01-18 04:59:56 +01:00
}
2010-01-28 05:39:27 +01:00
}
2010-01-18 04:59:56 +01:00
2010-01-28 05:39:27 +01:00
void
Module : : insert_menu_cb ( Fl_Widget * w , void * v )
{
( ( Module * ) v ) - > insert_menu_cb ( ( Fl_Menu_ * ) w ) ;
}
void
Module : : menu_cb ( const Fl_Menu_ * m )
{
char picked [ 256 ] ;
2010-02-04 20:05:25 +01:00
if ( ! m - > mvalue ( ) | | m - > mvalue ( ) - > flags & FL_SUBMENU_POINTER | | m - > mvalue ( ) - > flags & FL_SUBMENU )
return ;
2010-01-28 05:39:27 +01:00
strncpy ( picked , m - > mvalue ( ) - > label ( ) , sizeof ( picked ) ) ;
// m->item_pathname( picked, sizeof( picked ) );
DMESSAGE ( " %s " , picked ) ;
Logger log ( this ) ;
if ( ! strcmp ( picked , " Edit Parameters " ) )
command_open_parameter_editor ( ) ;
2010-02-01 01:50:08 +01:00
else if ( ! strcmp ( picked , " Bypass " ) )
2013-09-02 05:07:16 +02:00
{
2013-03-15 08:05:23 +01:00
if ( ! bypassable ( ) )
{
fl_alert ( " Due to its channel configuration, this module cannot be bypassed. " ) ;
}
else
{
2013-09-02 05:07:16 +02:00
bypass ( ! bypass ( ) ) ;
redraw ( ) ;
2013-03-15 08:05:23 +01:00
}
2013-09-02 05:07:16 +02:00
}
2010-01-14 04:20:40 +01:00
else if ( ! strcmp ( picked , " Cut " ) )
{
2013-08-28 08:02:36 +02:00
if ( copy ( ) )
{
chain ( ) - > remove ( this ) ;
Fl : : delete_widget ( this ) ;
}
2010-01-14 04:20:40 +01:00
}
else if ( ! strcmp ( picked , " Copy " ) )
{
copy ( ) ;
}
else if ( ! strcmp ( picked , " Paste " ) )
{
paste_before ( ) ;
}
2013-10-01 04:10:17 +02:00
else if ( ! strcmp ( picked , " Show Analysis " ) )
{
show_analysis_window ( ) ;
}
2010-01-28 05:39:27 +01:00
else if ( ! strcmp ( picked , " Remove " ) )
command_remove ( ) ;
}
2010-01-18 04:59:56 +01:00
2010-01-28 05:39:27 +01:00
void
Module : : menu_cb ( Fl_Widget * w , void * v )
{
( ( Module * ) v ) - > menu_cb ( ( Fl_Menu_ * ) w ) ;
}
2010-01-18 06:27:51 +01:00
2010-01-28 05:39:27 +01:00
/** build the context menu */
Fl_Menu_Button &
Module : : menu ( void ) const
{
static Fl_Menu_Button m ( 0 , 0 , 0 , 0 , " Module " ) ;
static Fl_Menu_Button * insert_menu = NULL ;
if ( ! insert_menu )
2010-01-18 06:27:51 +01:00
{
2010-01-28 05:39:27 +01:00
insert_menu = new Fl_Menu_Button ( 0 , 0 , 0 , 0 ) ;
2013-04-17 07:42:28 +02:00
insert_menu - > add ( " Gain " , 0 , 0 ) ;
insert_menu - > add ( " Meter " , 0 , 0 ) ;
insert_menu - > add ( " Mono Pan " , 0 , 0 ) ;
insert_menu - > add ( " Aux " , 0 , 0 ) ;
2013-06-27 08:49:29 +02:00
insert_menu - > add ( " Spatializer " , 0 , 0 ) ;
2013-04-17 07:42:28 +02:00
insert_menu - > add ( " Plugin " , 0 , 0 ) ;
2010-01-28 05:39:27 +01:00
insert_menu - > callback ( & Module : : insert_menu_cb , ( void * ) this ) ;
2010-01-18 06:27:51 +01:00
}
2010-01-18 04:59:56 +01:00
2010-01-28 05:39:27 +01:00
m . clear ( ) ;
m . add ( " Insert " , 0 , & Module : : menu_cb , ( void * ) this , 0 ) ;
m . add ( " Insert " , 0 , & Module : : menu_cb , const_cast < Fl_Menu_Item * > ( insert_menu - > menu ( ) ) , FL_SUBMENU_POINTER ) ;
2010-02-01 01:25:24 +01:00
m . add ( " Edit Parameters " , ' ' , & Module : : menu_cb , ( void * ) this , 0 ) ;
2013-10-01 04:10:17 +02:00
m . add ( " Show Analysis " , ' s ' , & Module : : menu_cb , ( void * ) this , 0 ) ;
2010-02-01 01:50:08 +01:00
m . add ( " Bypass " , ' b ' , & Module : : menu_cb , ( void * ) this , FL_MENU_TOGGLE | ( bypass ( ) ? FL_MENU_VALUE : 0 ) ) ;
2010-01-14 04:20:40 +01:00
m . add ( " Cut " , FL_CTRL + ' x ' , & Module : : menu_cb , ( void * ) this , is_default ( ) ? FL_MENU_INACTIVE : 0 ) ;
m . add ( " Copy " , FL_CTRL + ' c ' , & Module : : menu_cb , ( void * ) this , is_default ( ) ? FL_MENU_INACTIVE : 0 ) ;
m . add ( " Paste " , FL_CTRL + ' v ' , & Module : : menu_cb , ( void * ) this , _copied_module_empty ? 0 : FL_MENU_INACTIVE ) ;
2013-10-01 04:10:17 +02:00
2010-02-01 01:25:24 +01:00
m . add ( " Remove " , FL_Delete , & Module : : menu_cb , ( void * ) this ) ;
2010-01-28 05:39:27 +01:00
// menu_set_callback( menu, &Module::menu_cb, (void*)this );
m . callback ( & Module : : insert_menu_cb , ( void * ) this ) ;
2010-01-18 04:59:56 +01:00
return m ;
}
2012-02-08 04:44:40 +01:00
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 ( ) ;
2012-02-10 08:06:40 +01:00
control_input [ i ] . update_osc_port ( ) ;
2012-02-08 04:44:40 +01:00
}
2013-08-06 09:03:19 +02:00
if ( ! chain ( ) - > strip ( ) - > group ( ) - > single ( ) )
{
/* we have to rename our JACK ports... */
for ( unsigned int i = 0 ; i < aux_audio_input . size ( ) ; i + + )
{
aux_audio_input [ i ] . jack_port ( ) - > trackname ( chain ( ) - > name ( ) ) ;
aux_audio_input [ i ] . jack_port ( ) - > rename ( ) ;
}
for ( unsigned int i = 0 ; i < aux_audio_output . size ( ) ; i + + )
{
aux_audio_output [ i ] . jack_port ( ) - > trackname ( chain ( ) - > name ( ) ) ;
aux_audio_output [ i ] . jack_port ( ) - > rename ( ) ;
}
}
2012-02-08 04:44:40 +01:00
}
2009-12-25 01:59:39 +01:00
int
Module : : handle ( int m )
{
2013-04-23 06:54:45 +02:00
static unsigned long _event_state = 0 ;
unsigned long evstate = Fl : : event_state ( ) ;
2013-04-22 08:14:52 +02:00
2013-09-02 05:07:16 +02:00
switch ( m )
{
case FL_ENTER :
// Fl::focus(this);
case FL_LEAVE :
return 1 ;
}
2013-04-22 08:14:52 +02:00
if ( Fl_Group : : handle ( m ) )
return 1 ;
2009-12-25 01:59:39 +01:00
switch ( m )
{
2010-01-28 05:39:27 +01:00
case FL_KEYBOARD :
{
2010-01-30 09:38:15 +01:00
if ( Fl : : event_key ( ) = = FL_Menu )
2010-01-28 05:39:27 +01:00
{
menu_popup ( & menu ( ) , x ( ) , y ( ) ) ;
return 1 ;
}
else
return menu ( ) . test_shortcut ( ) ! = 0 ;
}
2013-04-22 08:14:52 +02:00
case FL_PUSH :
2010-02-01 01:25:14 +01:00
take_focus ( ) ;
2013-04-23 06:54:45 +02:00
_event_state = evstate ;
2013-04-22 08:14:52 +02:00
return 1 ;
// if ( Fl::visible_focus() && handle( FL_FOCUS )) Fl::focus(this);
case FL_DRAG :
2013-04-23 06:54:45 +02:00
_event_state = evstate ;
2013-04-22 08:14:52 +02:00
return 1 ;
case FL_RELEASE :
{
2013-04-23 06:54:45 +02:00
unsigned long e = _event_state ;
_event_state = 0 ;
if ( ! Fl : : event_inside ( this ) )
2010-01-28 05:39:27 +01:00
return 1 ;
2013-04-23 06:54:45 +02:00
2013-09-02 05:07:16 +02:00
if ( ( e & FL_BUTTON1 ) & & ( e & FL_CTRL ) )
{
Fl : : focus ( this ) ;
return 1 ;
}
else if ( e & FL_BUTTON1 )
2010-01-28 05:39:27 +01:00
{
command_open_parameter_editor ( ) ;
return 1 ;
}
2013-04-23 06:54:45 +02:00
else if ( e & FL_BUTTON3 & & e & FL_CTRL )
2009-12-25 01:59:39 +01:00
{
2010-01-28 05:39:27 +01:00
command_remove ( ) ;
return 1 ;
}
2013-04-23 06:54:45 +02:00
else if ( e & FL_BUTTON3 )
{
menu_popup ( & menu ( ) ) ;
return 1 ;
}
else if ( e & FL_BUTTON2 )
2010-01-31 07:59:46 +01:00
{
2013-03-15 08:05:23 +01:00
if ( ! bypassable ( ) )
{
fl_alert ( " Due to its channel configuration, this module cannot be bypassed. " ) ;
}
else
{
bypass ( ! bypass ( ) ) ;
redraw ( ) ;
}
2010-01-31 07:59:46 +01:00
return 1 ;
}
2013-04-22 08:14:52 +02:00
/* else */
/* { */
/* take_focus(); */
/* } */
2010-01-28 05:39:27 +01:00
return 0 ;
}
2010-02-01 01:25:14 +01:00
case FL_FOCUS :
case FL_UNFOCUS :
redraw ( ) ;
return 1 ;
2010-01-28 05:39:27 +01:00
}
2013-04-22 08:14:52 +02:00
return 0 ;
2010-01-28 05:39:27 +01:00
}
2009-12-25 01:59:39 +01:00
2013-08-06 09:03:19 +02:00
/*************/
/* AUX Ports */
/*************/
static char *
generate_port_name ( const char * aux , int direction , int n )
{
char * s ;
asprintf ( & s , " %s%s%s-%i " ,
aux ? aux : " " ,
aux ? " / " : " " ,
direction = = JACK : : Port : : Input ? " in " : " out " ,
n + 1 ) ;
return s ;
}
static void
jack_port_activation_error ( JACK : : Port * p )
{
fl_alert ( " Could not activate JACK port \" %s \" " , p - > name ( ) ) ;
}
/* freeze/disconnect all jack ports--used when changing groups */
void
Module : : freeze_ports ( void )
{
// 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 ( ) - > freeze_ports ( ) ;
}
for ( unsigned int i = 0 ; i < aux_audio_input . size ( ) ; + + i )
{
aux_audio_input [ i ] . jack_port ( ) - > freeze ( ) ;
aux_audio_input [ i ] . jack_port ( ) - > shutdown ( ) ;
}
for ( unsigned int i = 0 ; i < aux_audio_output . size ( ) ; + + i )
{
aux_audio_output [ i ] . jack_port ( ) - > freeze ( ) ;
aux_audio_output [ i ] . jack_port ( ) - > shutdown ( ) ;
}
}
/* rename and thaw all jack ports--used when changing groups */
void
Module : : thaw_ports ( void )
{
// 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 ( ) - > thaw_ports ( ) ;
}
const char * trackname = chain ( ) - > strip ( ) - > group ( ) - > single ( ) ? NULL : chain ( ) - > name ( ) ;
for ( unsigned int i = 0 ; i < aux_audio_input . size ( ) ; + + i )
{
/* if we're entering a group we need to add the chain name
* prefix and if we ' re leaving one , we need to remove it */
aux_audio_input [ i ] . jack_port ( ) - > client ( chain ( ) - > client ( ) ) ;
aux_audio_input [ i ] . jack_port ( ) - > trackname ( trackname ) ;
aux_audio_input [ i ] . jack_port ( ) - > thaw ( ) ;
}
for ( unsigned int i = 0 ; i < aux_audio_output . size ( ) ; + + i )
{
/* if we're entering a group we won't actually be using our
* JACK output ports anymore , just mixing into the group outputs */
aux_audio_output [ i ] . jack_port ( ) - > client ( chain ( ) - > client ( ) ) ;
aux_audio_output [ i ] . jack_port ( ) - > trackname ( trackname ) ;
aux_audio_output [ i ] . jack_port ( ) - > thaw ( ) ;
2013-09-04 10:00:29 +02:00
mixer - > maybe_auto_connect_output ( & aux_audio_output [ i ] ) ;
}
}
void
Module : : auto_connect_outputs ( void )
{
for ( unsigned int i = 0 ; i < aux_audio_output . size ( ) ; + + i )
{
mixer - > maybe_auto_connect_output ( & aux_audio_output [ i ] ) ;
}
}
void
Module : : auto_disconnect_outputs ( void )
{
for ( unsigned int i = 0 ; i < aux_audio_output . size ( ) ; + + i )
{
Module : : Port * p = & aux_audio_output [ i ] ;
if ( p - > connected_port ( ) )
{
p - > connected_port ( ) - > jack_port ( ) - > disconnect ( p - > jack_port ( ) - > jack_name ( ) ) ;
p - > disconnect ( ) ;
}
2013-08-06 09:03:19 +02:00
}
}
2013-09-15 04:27:03 +02:00
void
2013-09-12 09:07:18 +02:00
Module : : get_latency ( JACK : : Port : : direction_e dir , nframes_t * min , nframes_t * max ) const
2013-08-24 23:21:44 +02:00
{
2013-09-12 09:07:18 +02:00
nframes_t tmin = JACK_MAX_FRAMES > > 1 ;
2013-08-24 23:21:44 +02:00
nframes_t tmax = 0 ;
2013-09-15 04:27:03 +02:00
const std : : vector < Port > * ports ;
2013-08-24 23:21:44 +02:00
if ( dir = = JACK : : Port : : Input )
2013-09-15 04:27:03 +02:00
ports = & aux_audio_input ;
else
ports = & aux_audio_output ;
if ( ports - > size ( ) )
2013-08-24 23:21:44 +02:00
{
2013-09-15 04:27:03 +02:00
for ( unsigned int i = 0 ; i < ports - > size ( ) ; i + + )
2013-08-24 23:21:44 +02:00
{
2013-09-15 04:27:03 +02:00
/* if ( ! ports->[i].jack_port()->connected() ) */
/* continue; */
2013-09-12 09:07:18 +02:00
2013-09-15 04:27:03 +02:00
nframes_t min , max ;
( * ports ) [ i ] . jack_port ( ) - > get_latency ( dir , & min , & max ) ;
if ( min < tmin )
tmin = min ;
if ( max > tmax )
tmax = max ;
2013-09-12 09:07:18 +02:00
}
2013-08-24 23:21:44 +02:00
}
else
{
2013-09-15 04:27:03 +02:00
tmin = 0 ;
2013-08-24 23:21:44 +02:00
}
2013-09-12 09:07:18 +02:00
* min = tmin ;
* max = tmax ;
2013-08-24 23:21:44 +02:00
}
void
2013-09-12 09:07:18 +02:00
Module : : set_latency ( JACK : : Port : : direction_e dir , nframes_t min , nframes_t max )
2013-08-24 23:21:44 +02:00
{
2013-09-12 09:07:18 +02:00
if ( dir = = JACK : : Port : : Output )
2013-08-24 23:21:44 +02:00
{
2013-09-12 09:07:18 +02:00
for ( unsigned int i = 0 ; i < aux_audio_input . size ( ) ; i + + )
aux_audio_input [ i ] . jack_port ( ) - > set_latency ( dir , min , max ) ;
2013-08-24 23:21:44 +02:00
}
else
{
2013-09-12 09:07:18 +02:00
for ( unsigned int i = 0 ; i < aux_audio_output . size ( ) ; i + + )
aux_audio_output [ i ] . jack_port ( ) - > set_latency ( dir , min , max ) ;
2013-08-24 23:21:44 +02:00
}
}
2013-08-06 09:03:19 +02:00
bool
Module : : add_aux_port ( bool input , const char * prefix , int i )
{
const char * trackname = chain ( ) - > strip ( ) - > group ( ) - > single ( ) ? NULL : chain ( ) - > name ( ) ;
JACK : : Port : : direction_e direction = input ? JACK : : Port : : Input : JACK : : Port : : Output ;
char * portname = generate_port_name ( prefix , direction , i ) ;
JACK : : Port * po = new JACK : : Port ( chain ( ) - > client ( ) , trackname , portname , direction , JACK : : Port : : Audio ) ;
free ( portname ) ;
if ( ! po - > activate ( ) )
{
jack_port_activation_error ( po ) ;
return false ;
}
if ( po - > valid ( ) )
{
if ( input )
{
Module : : Port mp ( ( Module * ) this , Module : : Port : : INPUT , Module : : Port : : AUX_AUDIO ) ;
mp . jack_port ( po ) ;
aux_audio_input . push_back ( mp ) ;
}
else
{
Module : : Port mp ( ( Module * ) this , Module : : Port : : OUTPUT , Module : : Port : : AUX_AUDIO ) ;
mp . jack_port ( po ) ;
aux_audio_output . push_back ( mp ) ;
}
}
else
{
delete po ;
return false ;
}
return true ;
}
bool
Module : : add_aux_audio_output ( const char * prefix , int i )
{
2013-09-04 10:00:29 +02:00
bool r = add_aux_port ( false , prefix , i ) ;
if ( r )
mixer - > maybe_auto_connect_output ( & aux_audio_output . back ( ) ) ;
return r ;
2013-08-06 09:03:19 +02:00
}
bool
Module : : add_aux_audio_input ( const char * prefix , int i )
{
return add_aux_port ( true , prefix , i ) ;
}
2010-01-28 05:39:27 +01:00
/************/
/* Commands */
/************/
2009-12-25 01:59:39 +01:00
2010-01-28 05:39:27 +01:00
void
Module : : command_open_parameter_editor ( void )
{
if ( _editor )
{
_editor - > show ( ) ;
}
2013-04-17 04:18:02 +02:00
else if ( ncontrol_inputs ( ) & & nvisible_control_inputs ( ) )
2010-01-28 05:39:27 +01:00
{
DMESSAGE ( " Opening module parameters for \" %s \" " , label ( ) ) ;
_editor = new Module_Parameter_Editor ( this ) ;
2009-12-25 01:59:39 +01:00
2010-01-28 05:39:27 +01:00
_editor - > show ( ) ;
2009-12-25 01:59:39 +01:00
}
2010-01-28 05:39:27 +01:00
}
2009-12-25 01:59:39 +01:00
2010-01-28 05:39:27 +01:00
void
Module : : command_activate ( void )
{
bypass ( false ) ;
}
void
Module : : command_deactivate ( void )
{
bypass ( true ) ;
}
void
Module : : command_remove ( void )
{
if ( is_default ( ) )
fl_alert ( " Default modules may not be deleted. " ) ;
else
{
chain ( ) - > remove ( this ) ;
Fl : : delete_widget ( this ) ;
}
2009-12-25 01:59:39 +01:00
}