2007-06-27 16:23:48 -04:00
/*
Copyright ( C ) 2000 - 2004 Paul Davis
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 0213 9 , USA .
*/
2009-07-12 20:26:28 -04:00
# ifdef WAF_BUILD
# include "gtk2ardour-config.h"
# endif
2007-06-27 16:23:48 -04:00
# include <cmath>
# include <iostream>
2008-09-10 11:03:30 -04:00
# include <set>
2007-06-27 16:23:48 -04:00
# include <sigc++/bind.h>
2009-02-25 13:26:51 -05:00
# include "pbd/convert.h"
2016-03-14 06:48:22 -04:00
# include "canvas/utils.h"
2007-06-27 16:23:48 -04:00
# include <glibmm/miscutils.h>
2016-01-25 15:38:26 -05:00
# include <glibmm/fileutils.h>
2007-06-27 16:23:48 -04:00
# include <gtkmm/messagedialog.h>
# include <gtkmm2ext/gtk_ui.h>
# include <gtkmm2ext/utils.h>
# include <gtkmm2ext/choice.h>
# include <gtkmm2ext/utils.h>
# include <gtkmm2ext/doi.h>
2014-01-05 08:04:33 -05:00
# include <gtkmm2ext/rgb_macros.h>
2007-06-27 16:23:48 -04:00
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
# include "ardour/amp.h"
# include "ardour/audio_track.h"
# include "ardour/audioengine.h"
2010-11-27 16:32:29 -05:00
# include "ardour/internal_return.h"
2012-05-24 02:09:29 -04:00
# include "ardour/internal_send.h"
2016-01-25 15:38:26 -05:00
# include "ardour/luaproc.h"
# include "ardour/luascripting.h"
2015-05-18 10:30:02 -04:00
# include "ardour/meter.h"
2014-01-13 17:21:30 -05:00
# include "ardour/panner_shell.h"
2009-02-25 13:26:51 -05:00
# include "ardour/plugin_insert.h"
2014-01-13 04:48:37 -05:00
# include "ardour/pannable.h"
2009-02-25 13:26:51 -05:00
# include "ardour/port_insert.h"
# include "ardour/profile.h"
2009-05-07 13:31:18 -04:00
# include "ardour/return.h"
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
# include "ardour/route.h"
# include "ardour/send.h"
# include "ardour/session.h"
2012-05-24 02:09:29 -04:00
# include "ardour/types.h"
2007-06-27 16:23:48 -04:00
2016-03-28 13:14:56 -04:00
# include "LuaBridge/LuaBridge.h"
2009-05-07 13:31:18 -04:00
# include "actions.h"
2007-06-27 16:23:48 -04:00
# include "ardour_dialog.h"
2009-05-07 13:31:18 -04:00
# include "ardour_ui.h"
# include "gui_thread.h"
# include "io_selector.h"
2007-06-27 16:23:48 -04:00
# include "keyboard.h"
2016-03-18 16:33:45 -04:00
# include "luainstance.h"
2007-06-27 16:23:48 -04:00
# include "mixer_ui.h"
2009-05-16 22:08:13 -04:00
# include "mixer_strip.h"
2016-03-27 15:35:42 -04:00
# include "plugin_pin_dialog.h"
2009-05-07 13:31:18 -04:00
# include "plugin_selector.h"
2007-06-27 16:23:48 -04:00
# include "plugin_ui.h"
2010-08-31 10:16:29 -04:00
# include "port_insert_ui.h"
2009-05-07 13:31:18 -04:00
# include "processor_box.h"
# include "public_editor.h"
# include "return_ui.h"
# include "route_processor_selection.h"
2016-01-25 15:38:26 -05:00
# include "script_selector.h"
2009-05-07 13:31:18 -04:00
# include "send_ui.h"
2014-12-25 10:02:00 -05:00
# include "timers.h"
2015-01-05 00:32:14 -05:00
# include "tooltips.h"
2015-12-27 22:11:45 -05:00
# include "new_plugin_preset_dialog.h"
2007-06-27 16:23:48 -04:00
# include "i18n.h"
2011-10-18 11:08:42 -04:00
# ifdef AUDIOUNIT_SUPPORT
2008-09-10 11:03:30 -04:00
class AUPluginUI ;
2007-06-27 16:23:48 -04:00
# endif
2015-10-04 13:39:53 -04:00
# ifndef NDEBUG
bool ProcessorBox : : show_all_processors = false ;
# endif
2009-05-12 13:03:42 -04:00
using namespace std ;
2007-06-27 16:23:48 -04:00
using namespace ARDOUR ;
using namespace PBD ;
using namespace Gtk ;
using namespace Glib ;
using namespace Gtkmm2ext ;
2015-08-10 14:31:59 -04:00
ProcessorBox * ProcessorBox : : _current_processor_box = 0 ;
2007-06-27 16:23:48 -04:00
RefPtr < Action > ProcessorBox : : paste_action ;
2010-03-16 11:33:04 -04:00
RefPtr < Action > ProcessorBox : : cut_action ;
2015-08-15 15:29:19 -04:00
RefPtr < Action > ProcessorBox : : copy_action ;
2010-04-17 19:28:57 -04:00
RefPtr < Action > ProcessorBox : : rename_action ;
2015-08-15 15:29:19 -04:00
RefPtr < Action > ProcessorBox : : delete_action ;
2016-03-27 15:35:42 -04:00
RefPtr < Action > ProcessorBox : : manage_pins_action ;
2010-09-05 16:41:48 -04:00
RefPtr < Action > ProcessorBox : : edit_action ;
2012-01-21 17:10:07 -05:00
RefPtr < Action > ProcessorBox : : edit_generic_action ;
2016-03-15 12:40:53 -04:00
RefPtr < ActionGroup > ProcessorBox : : processor_box_actions ;
Gtkmm2ext : : ActionMap ProcessorBox : : myactions ( X_ ( " processor box " ) ) ;
Gtkmm2ext : : Bindings * ProcessorBox : : bindings = 0 ;
2009-11-25 09:37:20 -05:00
2016-03-31 14:44:39 -04:00
// TODO consolidate with PluginPinDialog::set_color
static void set_routing_color ( cairo_t * cr , bool midi )
{
static const uint32_t audio_port_color = 0x4A8A0EFF ; // Green
static const uint32_t midi_port_color = 0x960909FF ; //Red
if ( midi ) {
cairo_set_source_rgb ( cr ,
UINT_RGBA_R_FLT ( midi_port_color ) ,
UINT_RGBA_G_FLT ( midi_port_color ) ,
UINT_RGBA_B_FLT ( midi_port_color ) ) ;
} else {
cairo_set_source_rgb ( cr ,
UINT_RGBA_R_FLT ( audio_port_color ) ,
UINT_RGBA_G_FLT ( audio_port_color ) ,
UINT_RGBA_B_FLT ( audio_port_color ) ) ;
}
}
2014-01-05 08:04:33 -05:00
2012-01-21 15:32:13 -05:00
ProcessorEntry : : ProcessorEntry ( ProcessorBox * parent , boost : : shared_ptr < Processor > p , Width w )
2011-10-27 07:53:16 -04:00
: _button ( ArdourButton : : led_default_elements )
, _position ( PreFader )
2014-10-08 13:16:21 -04:00
, _position_num ( 0 )
2016-03-31 14:44:39 -04:00
, _parent ( parent )
2014-07-28 11:08:17 -04:00
, _selectable ( true )
2015-08-15 15:29:19 -04:00
, _unknown_processor ( false )
2011-01-31 20:50:49 -05:00
, _processor ( p )
2009-11-30 08:13:57 -05:00
, _width ( w )
2016-03-31 14:44:39 -04:00
, input_icon ( true )
, output_icon ( false )
2016-04-03 19:27:33 -04:00
, routing_icon ( true )
, output_routing_icon ( false )
2016-03-14 06:48:22 -04:00
, _plugin_display ( 0 )
2009-11-25 09:37:20 -05:00
{
2011-01-31 20:50:49 -05:00
_vbox . show ( ) ;
2015-10-05 10:17:49 -04:00
2011-10-27 07:53:16 -04:00
_button . set_distinct_led_click ( true ) ;
2014-08-28 16:24:16 -04:00
_button . set_fallthrough_to_parent ( true ) ;
2011-10-26 17:01:14 -04:00
_button . set_led_left ( true ) ;
2011-10-27 07:53:16 -04:00
_button . signal_led_clicked . connect ( sigc : : mem_fun ( * this , & ProcessorEntry : : led_clicked ) ) ;
2011-11-04 12:09:45 -04:00
_button . set_text ( name ( _width ) ) ;
2011-06-01 13:00:29 -04:00
2015-05-18 10:30:02 -04:00
if ( boost : : dynamic_pointer_cast < PeakMeter > ( _processor ) ) {
_button . set_elements ( ArdourButton : : Element ( _button . elements ( ) & ~ ArdourButton : : Indicator ) ) ;
}
2015-08-15 14:49:52 -04:00
if ( boost : : dynamic_pointer_cast < UnknownProcessor > ( _processor ) ) {
_button . set_elements ( ArdourButton : : Element ( _button . elements ( ) & ~ ArdourButton : : Indicator ) ) ;
2015-08-15 15:29:19 -04:00
_unknown_processor = true ;
2015-08-15 14:49:52 -04:00
}
2015-12-27 22:11:45 -05:00
{
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( _processor ) ;
2016-04-29 12:34:41 -04:00
if ( pi & & pi - > plugin ( ) ) {
2015-12-27 22:11:45 -05:00
_plugin_preset_pointer = PluginPresetPtr ( new PluginPreset ( pi - > plugin ( ) - > get_info ( ) ) ) ;
}
}
2012-01-07 12:10:18 -05:00
if ( _processor ) {
2012-01-21 11:38:45 -05:00
2016-03-31 14:44:39 -04:00
_vbox . pack_start ( routing_icon ) ;
_vbox . pack_start ( input_icon ) ;
2012-01-07 12:10:18 -05:00
_vbox . pack_start ( _button , true , true ) ;
2016-03-14 06:48:22 -04:00
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( _processor ) ;
if ( pi & & pi - > plugin ( ) & & pi - > plugin ( ) - > has_inline_display ( ) ) {
2016-03-18 16:33:45 -04:00
if ( pi - > plugin ( ) - > get_info ( ) - > type ! = ARDOUR : : Lua ) {
_plugin_display = new PluginDisplay ( pi - > plugin ( ) ,
std : : max ( 60.f , rintf ( 112.f * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ) ;
} else {
assert ( boost : : dynamic_pointer_cast < LuaProc > ( pi - > plugin ( ) ) ) ;
_plugin_display = new LuaPluginDisplay ( boost : : dynamic_pointer_cast < LuaProc > ( pi - > plugin ( ) ) ,
std : : max ( 60.f , rintf ( 112.f * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ) ;
}
2016-03-14 06:48:22 -04:00
_vbox . pack_start ( * _plugin_display ) ;
_plugin_display - > set_no_show_all ( true ) ;
2016-03-15 10:15:23 -04:00
if ( UIConfiguration : : instance ( ) . get_show_inline_display_by_default ( ) ) {
2016-03-14 06:48:22 -04:00
_plugin_display - > show ( ) ;
}
}
2016-04-03 19:27:33 -04:00
_vbox . pack_end ( output_routing_icon ) ;
2016-03-31 14:44:39 -04:00
_vbox . pack_end ( output_icon ) ;
2011-10-26 17:01:14 -04:00
2012-02-07 12:43:55 -05:00
_button . set_active ( _processor - > active ( ) ) ;
2014-01-03 23:54:20 -05:00
2016-03-31 14:44:39 -04:00
input_icon . set_no_show_all ( true ) ;
2016-04-08 18:33:56 -04:00
routing_icon . set_no_show_all ( true ) ;
output_icon . set_no_show_all ( true ) ;
output_routing_icon . set_no_show_all ( true ) ;
2014-01-06 17:00:11 -05:00
2012-01-07 12:10:18 -05:00
_button . show ( ) ;
2016-03-31 14:44:39 -04:00
input_icon . hide ( ) ;
output_icon . show ( ) ;
2016-04-03 19:27:33 -04:00
routing_icon . hide ( ) ;
output_routing_icon . hide ( ) ;
2013-06-06 17:55:08 -04:00
2012-01-07 12:10:18 -05:00
_processor - > ActiveChanged . connect ( active_connection , invalidator ( * this ) , boost : : bind ( & ProcessorEntry : : processor_active_changed , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_processor - > PropertyChanged . connect ( name_connection , invalidator ( * this ) , boost : : bind ( & ProcessorEntry : : processor_property_changed , this , _1 ) , gui_context ( ) ) ;
2014-01-03 23:54:20 -05:00
_processor - > ConfigurationChanged . connect ( config_connection , invalidator ( * this ) , boost : : bind ( & ProcessorEntry : : processor_configuration_changed , this , _1 , _2 ) , gui_context ( ) ) ;
2012-01-07 12:10:18 -05:00
2012-01-20 13:02:48 -05:00
set < Evoral : : Parameter > p = _processor - > what_can_be_automated ( ) ;
for ( set < Evoral : : Parameter > : : iterator i = p . begin ( ) ; i ! = p . end ( ) ; + + i ) {
2015-10-05 10:17:49 -04:00
2014-01-05 15:05:48 -05:00
std : : string label = _processor - > describe_parameter ( * i ) ;
if ( boost : : dynamic_pointer_cast < Send > ( _processor ) ) {
label = _ ( " Send " ) ;
} else if ( boost : : dynamic_pointer_cast < Return > ( _processor ) ) {
label = _ ( " Return " ) ;
}
Control * c = new Control ( _processor - > automation_control ( * i ) , label ) ;
2015-10-05 10:17:49 -04:00
2012-01-21 15:32:13 -05:00
_controls . push_back ( c ) ;
if ( boost : : dynamic_pointer_cast < Amp > ( _processor ) = = 0 ) {
2015-09-21 07:14:29 -04:00
/* Add non-Amp (Fader & Trim) controls to the processor box */
2012-01-21 15:32:13 -05:00
_vbox . pack_start ( c - > box ) ;
2012-01-20 13:02:48 -05:00
}
}
2012-01-07 12:10:18 -05:00
setup_tooltip ( ) ;
setup_visuals ( ) ;
} else {
_vbox . set_size_request ( - 1 , _button . size_request ( ) . height ) ;
}
2009-11-25 09:37:20 -05:00
}
2012-01-21 11:38:45 -05:00
ProcessorEntry : : ~ ProcessorEntry ( )
{
for ( list < Control * > : : iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
delete * i ;
}
2016-03-14 06:48:22 -04:00
delete _plugin_display ;
2012-01-21 11:38:45 -05:00
}
2009-11-25 09:37:20 -05:00
EventBox &
ProcessorEntry : : action_widget ( )
{
2011-10-26 17:01:14 -04:00
return _button ;
2009-11-25 09:37:20 -05:00
}
Gtk : : Widget &
ProcessorEntry : : widget ( )
{
2011-10-26 17:01:14 -04:00
return _vbox ;
2009-11-25 09:37:20 -05:00
}
string
ProcessorEntry : : drag_text ( ) const
{
2011-11-04 12:09:45 -04:00
return name ( Wide ) ;
2009-11-25 09:37:20 -05:00
}
2016-03-11 16:00:12 -05:00
bool
ProcessorEntry : : can_copy_state ( Gtkmm2ext : : DnDVBoxChild * o ) const
{
ProcessorEntry * other = dynamic_cast < ProcessorEntry * > ( o ) ;
if ( ! other ) {
return false ;
}
boost : : shared_ptr < ARDOUR : : Processor > otherproc = other - > processor ( ) ;
boost : : shared_ptr < PluginInsert > my_pi = boost : : dynamic_pointer_cast < PluginInsert > ( _processor ) ;
boost : : shared_ptr < PluginInsert > ot_pi = boost : : dynamic_pointer_cast < PluginInsert > ( otherproc ) ;
if ( boost : : dynamic_pointer_cast < UnknownProcessor > ( _processor ) ) {
return false ;
}
if ( boost : : dynamic_pointer_cast < UnknownProcessor > ( otherproc ) ) {
return false ;
}
if ( ! my_pi | | ! ot_pi ) {
return false ;
}
if ( my_pi - > type ( ) ! = ot_pi - > type ( ) ) {
return false ;
}
boost : : shared_ptr < Plugin > my_p = my_pi - > plugin ( ) ;
boost : : shared_ptr < Plugin > ot_p = ot_pi - > plugin ( ) ;
if ( ! my_p | | ! ot_p ) {
return false ;
}
if ( my_p - > unique_id ( ) ! = ot_p - > unique_id ( ) ) {
return false ;
}
return true ;
}
2015-12-27 22:11:45 -05:00
bool
ProcessorEntry : : drag_data_get ( Glib : : RefPtr < Gdk : : DragContext > const , Gtk : : SelectionData & data )
{
2015-12-30 06:15:25 -05:00
if ( data . get_target ( ) = = " PluginPresetPtr " ) {
2015-12-27 22:11:45 -05:00
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( _processor ) ;
2015-12-30 06:15:25 -05:00
if ( ! _plugin_preset_pointer | | ! pi ) {
data . set ( data . get_target ( ) , 8 , NULL , 0 ) ;
return true ;
}
2015-12-27 22:11:45 -05:00
boost : : shared_ptr < ARDOUR : : Plugin > plugin = pi - > plugin ( ) ;
assert ( plugin ) ;
2015-12-28 10:08:35 -05:00
PluginManager & manager ( PluginManager : : instance ( ) ) ;
bool fav = manager . get_status ( _plugin_preset_pointer - > _pip ) = = PluginManager : : Favorite ;
NewPluginPresetDialog d ( plugin ,
string_compose ( _ ( " New Favorite Preset for \" %1 \" " ) , _plugin_preset_pointer - > _pip - > name ) , ! fav ) ;
2015-12-27 22:11:45 -05:00
_plugin_preset_pointer - > _preset . valid = false ;
switch ( d . run ( ) ) {
2015-12-28 10:08:35 -05:00
case Gtk : : RESPONSE_CANCEL :
data . set ( data . get_target ( ) , 8 , NULL , 0 ) ;
return true ;
break ;
case Gtk : : RESPONSE_NO :
break ;
2015-12-27 22:11:45 -05:00
case Gtk : : RESPONSE_ACCEPT :
if ( d . name ( ) . empty ( ) ) {
break ;
}
if ( d . replace ( ) ) {
plugin - > remove_preset ( d . name ( ) ) ;
}
Plugin : : PresetRecord const r = plugin - > save_preset ( d . name ( ) ) ;
if ( ! r . uri . empty ( ) ) {
_plugin_preset_pointer - > _preset . uri = r . uri ;
_plugin_preset_pointer - > _preset . label = r . label ;
_plugin_preset_pointer - > _preset . user = r . user ;
_plugin_preset_pointer - > _preset . valid = r . valid ;
}
}
data . set ( data . get_target ( ) , 8 , ( const guchar * ) & _plugin_preset_pointer , sizeof ( PluginPresetPtr ) ) ;
return true ;
}
return false ;
}
2009-11-25 09:37:20 -05:00
2011-01-14 10:48:45 -05:00
void
2014-01-05 09:50:13 -05:00
ProcessorEntry : : set_position ( Position p , uint32_t num )
2011-01-14 10:48:45 -05:00
{
2011-10-26 17:01:14 -04:00
_position = p ;
2014-01-05 09:50:13 -05:00
_position_num = num ;
2011-01-14 10:48:45 -05:00
setup_visuals ( ) ;
}
void
2011-10-31 21:22:08 -04:00
ProcessorEntry : : set_visual_state ( Gtkmm2ext : : VisualState s , bool yn )
2011-01-14 10:48:45 -05:00
{
2011-10-31 21:22:08 -04:00
if ( yn ) {
_button . set_visual_state ( Gtkmm2ext : : VisualState ( _button . visual_state ( ) | s ) ) ;
} else {
_button . set_visual_state ( Gtkmm2ext : : VisualState ( _button . visual_state ( ) & ~ s ) ) ;
2011-10-26 17:01:14 -04:00
}
2011-01-14 10:48:45 -05:00
}
void
ProcessorEntry : : setup_visuals ( )
{
2015-08-15 15:29:19 -04:00
if ( _unknown_processor ) {
_button . set_name ( " processor stub " ) ;
return ;
}
2016-04-17 08:10:13 -04:00
boost : : shared_ptr < Send > send ;
if ( ( send = boost : : dynamic_pointer_cast < Send > ( _processor ) ) ) {
if ( send - > remove_on_disconnect ( ) ) {
_button . set_name ( " processor sidechain " ) ;
return ;
}
}
2015-08-15 15:29:19 -04:00
2011-01-14 10:48:45 -05:00
switch ( _position ) {
case PreFader :
2016-03-14 06:48:22 -04:00
if ( _plugin_display ) { _plugin_display - > set_name ( " processor prefader " ) ; }
2011-10-26 17:01:14 -04:00
_button . set_name ( " processor prefader " ) ;
2011-01-14 10:48:45 -05:00
break ;
case Fader :
2011-10-26 17:01:14 -04:00
_button . set_name ( " processor fader " ) ;
2011-01-14 10:48:45 -05:00
break ;
case PostFader :
2016-03-14 06:48:22 -04:00
if ( _plugin_display ) { _plugin_display - > set_name ( " processor postfader " ) ; }
2011-10-26 17:01:14 -04:00
_button . set_name ( " processor postfader " ) ;
2011-01-14 17:26:45 -05:00
break ;
2011-01-14 10:48:45 -05:00
}
}
2011-06-01 13:00:29 -04:00
2011-01-14 10:48:45 -05:00
2009-11-25 09:37:20 -05:00
boost : : shared_ptr < Processor >
ProcessorEntry : : processor ( ) const
{
2016-03-11 16:00:12 -05:00
if ( ! _processor ) {
return boost : : shared_ptr < Processor > ( ) ;
}
2009-11-25 09:37:20 -05:00
return _processor ;
}
void
2009-12-04 12:45:11 -05:00
ProcessorEntry : : set_enum_width ( Width w )
2009-11-25 09:37:20 -05:00
{
_width = w ;
2013-07-19 04:37:49 -04:00
_button . set_text ( name ( _width ) ) ;
2009-11-25 09:37:20 -05:00
}
void
2015-10-14 06:38:44 -04:00
ProcessorEntry : : led_clicked ( GdkEventButton * ev )
2009-11-25 09:37:20 -05:00
{
2015-10-14 06:38:44 -04:00
bool ctrl_shift_pressed = false ;
Keyboard : : ModifierMask ctrl_shift_mask = Keyboard : : ModifierMask ( Keyboard : : PrimaryModifier | Keyboard : : TertiaryModifier ) ;
if ( Keyboard : : modifier_state_equals ( ev - > state , ctrl_shift_mask ) ) {
ctrl_shift_pressed = true ;
}
2012-01-07 12:10:18 -05:00
if ( _processor ) {
2012-02-07 12:43:55 -05:00
if ( _button . get_active ( ) ) {
2015-10-14 06:38:44 -04:00
if ( ctrl_shift_pressed ) {
_parent - > all_visible_processors_active ( false ) ;
if ( _position = = Fader ) {
_processor - > deactivate ( ) ;
}
}
else {
_processor - > deactivate ( ) ;
}
2012-01-07 12:10:18 -05:00
} else {
2015-10-14 06:38:44 -04:00
if ( ctrl_shift_pressed ) {
_parent - > all_visible_processors_active ( true ) ;
if ( _position = = Fader ) {
_processor - > activate ( ) ;
}
}
else {
_processor - > activate ( ) ;
}
2012-01-07 12:10:18 -05:00
}
2009-11-25 09:37:20 -05:00
}
}
void
ProcessorEntry : : processor_active_changed ( )
{
2012-01-07 12:10:18 -05:00
if ( _processor ) {
2012-02-07 12:43:55 -05:00
_button . set_active ( _processor - > active ( ) ) ;
2011-10-27 07:24:43 -04:00
}
2009-11-25 09:37:20 -05:00
}
void
2010-02-19 13:09:08 -05:00
ProcessorEntry : : processor_property_changed ( const PropertyChange & what_changed )
2009-11-25 09:37:20 -05:00
{
2010-02-19 13:09:08 -05:00
if ( what_changed . contains ( ARDOUR : : Properties : : name ) ) {
2011-11-04 12:09:45 -04:00
_button . set_text ( name ( _width ) ) ;
setup_tooltip ( ) ;
2010-02-19 13:09:08 -05:00
}
2009-11-25 09:37:20 -05:00
}
2014-01-03 23:54:20 -05:00
void
ProcessorEntry : : processor_configuration_changed ( const ChanCount in , const ChanCount out )
{
2016-03-31 14:44:39 -04:00
_parent - > setup_routing_feeds ( ) ;
input_icon . queue_draw ( ) ;
output_icon . queue_draw ( ) ;
routing_icon . queue_draw ( ) ;
2016-04-03 19:27:33 -04:00
output_routing_icon . queue_draw ( ) ;
2014-01-03 23:54:20 -05:00
}
2011-11-04 12:09:45 -04:00
void
ProcessorEntry : : setup_tooltip ( )
{
2013-06-06 17:55:08 -04:00
if ( _processor ) {
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( _processor ) ;
if ( pi ) {
2014-01-10 06:12:06 -05:00
std : : string postfix = " " ;
uint32_t replicated ;
if ( ( replicated = pi - > get_count ( ) ) > 1 ) {
postfix = string_compose ( _ ( " \n This mono plugin has been replicated %1 times. " ) , replicated ) ;
}
2013-06-06 17:55:08 -04:00
if ( pi - > plugin ( ) - > has_editor ( ) ) {
2015-01-05 00:32:14 -05:00
ARDOUR_UI_UTILS : : set_tooltip ( _button ,
2015-11-20 16:24:47 -05:00
string_compose ( _ ( " <b>%1</b> \n Double-click to show GUI. \n %2+double-click to show generic GUI.%3 " ) , name ( Wide ) , Keyboard : : primary_modifier_name ( ) , postfix ) ) ;
2013-06-06 17:55:08 -04:00
} else {
2015-01-05 00:32:14 -05:00
ARDOUR_UI_UTILS : : set_tooltip ( _button ,
2014-01-10 06:12:06 -05:00
string_compose ( _ ( " <b>%1</b> \n Double-click to show generic GUI.%2 " ) , name ( Wide ) , postfix ) ) ;
2013-06-06 17:55:08 -04:00
}
return ;
}
2015-08-15 15:29:19 -04:00
if ( boost : : dynamic_pointer_cast < UnknownProcessor > ( _processor ) ) {
ARDOUR_UI : : instance ( ) - > set_tip ( _button ,
string_compose ( _ ( " <b>%1</b> \n The Plugin is not available on this system \n and has been replaced by a stub. " ) , name ( Wide ) ) ) ;
return ;
}
2016-04-17 19:01:49 -04:00
boost : : shared_ptr < Send > send ;
if ( ( send = boost : : dynamic_pointer_cast < Send > ( _processor ) ) ! = 0 & &
! boost : : dynamic_pointer_cast < InternalSend > ( _processor ) ) {
if ( send - > remove_on_disconnect ( ) ) {
ARDOUR_UI_UTILS : : set_tooltip ( _button , string_compose ( " <b>> %1</b> \n This (sidechain) send will be removed when disconnected. " , _processor - > name ( ) ) ) ;
} else {
ARDOUR_UI_UTILS : : set_tooltip ( _button , string_compose ( " <b>> %1</b> " , _processor - > name ( ) ) ) ;
}
2016-04-17 15:37:43 -04:00
return ;
}
2013-06-06 17:55:08 -04:00
}
2015-01-05 00:32:14 -05:00
ARDOUR_UI_UTILS : : set_tooltip ( _button , string_compose ( " <b>%1</b> " , name ( Wide ) ) ) ;
2011-11-04 12:09:45 -04:00
}
2009-11-25 09:37:20 -05:00
string
2011-11-04 12:09:45 -04:00
ProcessorEntry : : name ( Width w ) const
2009-11-25 09:37:20 -05:00
{
boost : : shared_ptr < Send > send ;
string name_display ;
2011-06-01 13:00:29 -04:00
2012-01-07 12:10:18 -05:00
if ( ! _processor ) {
return string ( ) ;
}
2009-11-25 09:37:20 -05:00
if ( ( send = boost : : dynamic_pointer_cast < Send > ( _processor ) ) ! = 0 & &
! boost : : dynamic_pointer_cast < InternalSend > ( _processor ) ) {
2011-06-01 13:00:29 -04:00
2009-11-25 09:37:20 -05:00
name_display + = ' > ' ;
2016-04-17 15:37:43 -04:00
std : : string send_name ;
bool pretty_ok = true ;
2011-06-01 13:00:29 -04:00
2016-04-17 15:37:43 -04:00
if ( send - > remove_on_disconnect ( ) ) {
// assume it's a sidechain, find pretty name of connected port(s)
PortSet & ps ( send - > output ( ) - > ports ( ) ) ;
for ( PortSet : : iterator i = ps . begin ( ) ; i ! = ps . end ( ) & & pretty_ok ; + + i ) {
vector < string > connections ;
if ( i - > get_connections ( connections ) ) {
vector < string > : : const_iterator ci ;
for ( ci = connections . begin ( ) ; ci ! = connections . end ( ) ; + + ci ) {
std : : string pn = AudioEngine : : instance ( ) - > get_pretty_name_by_name ( * ci ) ;
if ( pn . empty ( ) ) {
continue ;
}
if ( send_name . empty ( ) ) {
send_name = pn ;
} else if ( send_name ! = pn ) {
// pretty names don't match
pretty_ok = false ;
break ;
}
}
}
}
}
if ( ! pretty_ok ) {
send_name = " " ;
}
2011-06-01 13:00:29 -04:00
2016-04-17 15:37:43 -04:00
/* grab the send name out of its overall name */
if ( send_name . empty ( ) ) {
send_name = send - > name ( ) ;
string : : size_type lbracket , rbracket ;
lbracket = send_name . find ( ' [ ' ) ;
rbracket = send_name . find ( ' ] ' ) ;
send_name = send_name . substr ( lbracket + 1 , lbracket - rbracket - 1 ) ;
}
2011-06-01 13:00:29 -04:00
2011-11-04 12:09:45 -04:00
switch ( w ) {
2009-11-25 09:37:20 -05:00
case Wide :
2016-04-17 15:37:43 -04:00
name_display + = send_name ;
2009-11-25 09:37:20 -05:00
break ;
case Narrow :
2016-04-17 15:37:43 -04:00
name_display + = PBD : : short_version ( send_name , 5 ) ;
2009-11-25 09:37:20 -05:00
break ;
}
2011-06-01 13:00:29 -04:00
2009-11-25 09:37:20 -05:00
} else {
2014-01-10 06:12:06 -05:00
boost : : shared_ptr < ARDOUR : : PluginInsert > pi ;
uint32_t replicated ;
if ( ( pi = boost : : dynamic_pointer_cast < ARDOUR : : PluginInsert > ( _processor ) ) ! = 0
& & ( replicated = pi - > get_count ( ) ) > 1 )
{
name_display + = string_compose ( _ ( " (%1x1) " ) , replicated ) ;
}
2011-06-01 13:00:29 -04:00
2011-11-04 12:09:45 -04:00
switch ( w ) {
2009-11-25 09:37:20 -05:00
case Wide :
name_display + = _processor - > display_name ( ) ;
break ;
case Narrow :
name_display + = PBD : : short_version ( _processor - > display_name ( ) , 5 ) ;
break ;
}
2011-06-01 13:00:29 -04:00
2009-11-25 09:37:20 -05:00
}
2011-06-01 13:00:29 -04:00
2009-11-25 09:37:20 -05:00
return name_display ;
}
2012-01-20 13:02:48 -05:00
void
ProcessorEntry : : show_all_controls ( )
{
for ( list < Control * > : : iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
2012-01-21 15:32:13 -05:00
( * i ) - > set_visible ( true ) ;
2012-01-20 13:02:48 -05:00
}
2012-01-21 15:32:13 -05:00
_parent - > update_gui_object_state ( this ) ;
2012-01-20 13:02:48 -05:00
}
void
ProcessorEntry : : hide_all_controls ( )
{
for ( list < Control * > : : iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
2012-01-21 15:32:13 -05:00
( * i ) - > set_visible ( false ) ;
2012-01-20 13:02:48 -05:00
}
2012-01-21 15:32:13 -05:00
_parent - > update_gui_object_state ( this ) ;
2012-01-20 13:02:48 -05:00
}
void
ProcessorEntry : : add_control_state ( XMLNode * node ) const
{
for ( list < Control * > : : const_iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
( * i ) - > add_state ( node ) ;
}
2016-03-14 06:48:22 -04:00
if ( _plugin_display ) {
XMLNode * c = new XMLNode ( X_ ( " Object " ) ) ;
c - > add_property ( X_ ( " id " ) , X_ ( " InlineDisplay " ) ) ;
c - > add_property ( X_ ( " visible " ) , _plugin_display - > is_visible ( ) ) ;
node - > add_child_nocopy ( * c ) ;
}
2012-01-20 13:02:48 -05:00
}
void
ProcessorEntry : : set_control_state ( XMLNode const * node )
{
for ( list < Control * > : : const_iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
( * i ) - > set_state ( node ) ;
}
2016-03-14 06:48:22 -04:00
if ( _plugin_display ) {
XMLNode * n = GUIObjectState : : get_node ( node , X_ ( " InlineDisplay " ) ) ;
2016-05-04 23:09:37 -04:00
XMLProperty const * p = n ? n - > property ( X_ ( " visible " ) ) : NULL ;
2016-03-14 06:48:22 -04:00
if ( p ) {
if ( string_is_affirmative ( p - > value ( ) ) ) {
_plugin_display - > show ( ) ;
} else {
_plugin_display - > hide ( ) ;
}
}
}
2012-01-20 13:02:48 -05:00
}
string
ProcessorEntry : : state_id ( ) const
{
return string_compose ( " processor %1 " , _processor - > id ( ) . to_s ( ) ) ;
}
void
ProcessorEntry : : hide_things ( )
{
for ( list < Control * > : : iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
( * i ) - > hide_things ( ) ;
}
}
2012-01-21 15:32:13 -05:00
Menu *
ProcessorEntry : : build_controls_menu ( )
{
using namespace Menu_Helpers ;
Menu * menu = manage ( new Menu ) ;
MenuList & items = menu - > items ( ) ;
2016-03-14 06:48:22 -04:00
if ( _plugin_display ) {
items . push_back ( CheckMenuElem ( _ ( " Inline Display " ) ) ) ;
Gtk : : CheckMenuItem * c = dynamic_cast < Gtk : : CheckMenuItem * > ( & items . back ( ) ) ;
c - > set_active ( _plugin_display - > is_visible ( ) ) ;
c - > signal_toggled ( ) . connect ( sigc : : mem_fun ( * this , & ProcessorEntry : : toggle_inline_display_visibility ) ) ;
items . push_back ( SeparatorElem ( ) ) ;
}
2012-01-21 15:32:13 -05:00
items . push_back (
MenuElem ( _ ( " Show All Controls " ) , sigc : : mem_fun ( * this , & ProcessorEntry : : show_all_controls ) )
) ;
2015-10-05 10:17:49 -04:00
2012-01-21 15:32:13 -05:00
items . push_back (
MenuElem ( _ ( " Hide All Controls " ) , sigc : : mem_fun ( * this , & ProcessorEntry : : hide_all_controls ) )
) ;
if ( ! _controls . empty ( ) ) {
items . push_back ( SeparatorElem ( ) ) ;
}
2015-10-05 10:17:49 -04:00
2012-01-21 15:32:13 -05:00
for ( list < Control * > : : iterator i = _controls . begin ( ) ; i ! = _controls . end ( ) ; + + i ) {
items . push_back ( CheckMenuElem ( ( * i ) - > name ( ) ) ) ;
2013-07-11 15:32:31 -04:00
Gtk : : CheckMenuItem * c = dynamic_cast < Gtk : : CheckMenuItem * > ( & items . back ( ) ) ;
2012-01-21 15:32:13 -05:00
c - > set_active ( ( * i ) - > visible ( ) ) ;
c - > signal_toggled ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & ProcessorEntry : : toggle_control_visibility ) , * i ) ) ;
}
return menu ;
}
2016-03-14 06:48:22 -04:00
void
ProcessorEntry : : toggle_inline_display_visibility ( )
{
if ( _plugin_display - > is_visible ( ) ) {
_plugin_display - > hide ( ) ;
} else {
_plugin_display - > show ( ) ;
}
_parent - > update_gui_object_state ( this ) ;
}
2012-01-21 15:32:13 -05:00
void
ProcessorEntry : : toggle_control_visibility ( Control * c )
{
c - > set_visible ( ! c - > visible ( ) ) ;
_parent - > update_gui_object_state ( this ) ;
}
2014-01-13 17:21:30 -05:00
Menu *
ProcessorEntry : : build_send_options_menu ( )
{
using namespace Menu_Helpers ;
Menu * menu = manage ( new Menu ) ;
MenuList & items = menu - > items ( ) ;
boost : : shared_ptr < Send > send = boost : : dynamic_pointer_cast < Send > ( _processor ) ;
if ( send ) {
items . push_back ( CheckMenuElem ( _ ( " Link panner controls " ) ) ) ;
2014-01-30 13:28:12 -05:00
Gtk : : CheckMenuItem * c = dynamic_cast < Gtk : : CheckMenuItem * > ( & items . back ( ) ) ;
2014-01-13 17:21:30 -05:00
c - > set_active ( send - > panner_shell ( ) - > is_linked_to_route ( ) ) ;
c - > signal_toggled ( ) . connect ( sigc : : mem_fun ( * this , & ProcessorEntry : : toggle_panner_link ) ) ;
}
return menu ;
}
void
ProcessorEntry : : toggle_panner_link ( )
{
boost : : shared_ptr < Send > send = boost : : dynamic_pointer_cast < Send > ( _processor ) ;
if ( send ) {
send - > panner_shell ( ) - > set_linked_to_route ( ! send - > panner_shell ( ) - > is_linked_to_route ( ) ) ;
}
}
2013-01-10 10:25:11 -05:00
ProcessorEntry : : Control : : Control ( boost : : shared_ptr < AutomationControl > c , string const & n )
2012-01-20 13:02:48 -05:00
: _control ( c )
, _adjustment ( gain_to_slider_position_with_max ( 1.0 , Config - > get_max_gain ( ) ) , 0 , 1 , 0.01 , 0.1 )
2015-01-02 09:44:54 -05:00
, _slider ( & _adjustment , boost : : shared_ptr < PBD : : Controllable > ( ) , 0 , max ( 13.f , rintf ( 13.f * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) )
2012-06-11 17:21:10 -04:00
, _slider_persistant_tooltip ( & _slider )
2014-01-05 07:13:28 -05:00
, _button ( ArdourButton : : led_default_elements )
2012-01-21 17:54:36 -05:00
, _ignore_ui_adjustment ( false )
2012-01-20 13:02:48 -05:00
, _visible ( false )
2012-01-21 15:32:13 -05:00
, _name ( n )
2012-01-20 13:02:48 -05:00
{
_slider . set_controllable ( c ) ;
2014-01-04 13:03:47 -05:00
box . set_padding ( 0 , 0 , 4 , 4 ) ;
2012-01-20 13:02:48 -05:00
2012-01-21 17:54:36 -05:00
if ( c - > toggled ( ) ) {
_button . set_text ( _name ) ;
_button . set_led_left ( true ) ;
_button . set_name ( " processor control button " ) ;
2014-01-04 13:03:47 -05:00
box . add ( _button ) ;
2012-01-21 17:54:36 -05:00
_button . show ( ) ;
2012-01-21 11:38:45 -05:00
2012-01-21 17:54:36 -05:00
_button . signal_clicked . connect ( sigc : : mem_fun ( * this , & Control : : button_clicked ) ) ;
2015-10-14 06:38:44 -04:00
_button . signal_led_clicked . connect ( sigc : : mem_fun ( * this , & Control : : button_clicked_event ) ) ;
2015-08-19 07:49:30 -04:00
// dup. currently timers are used :(
//c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
2012-01-20 13:02:48 -05:00
2012-01-21 17:54:36 -05:00
} else {
2015-10-05 10:17:49 -04:00
2014-01-05 07:07:31 -05:00
_slider . set_name ( " ProcessorControlSlider " ) ;
2012-12-10 15:08:36 -05:00
_slider . set_text ( _name ) ;
2014-01-04 13:03:47 -05:00
box . add ( _slider ) ;
2012-01-21 17:54:36 -05:00
_slider . show ( ) ;
2014-11-30 18:33:11 -05:00
const ARDOUR : : ParameterDescriptor & desc = c - > desc ( ) ;
double const lo = c - > internal_to_interface ( desc . lower ) ;
double const up = c - > internal_to_interface ( desc . upper ) ;
double const normal = c - > internal_to_interface ( desc . normal ) ;
double smallstep = desc . smallstep ;
double largestep = desc . largestep ;
if ( smallstep = = 0.0 ) {
smallstep = up / 1000. ;
} else {
smallstep = c - > internal_to_interface ( desc . lower + smallstep ) ;
}
if ( largestep = = 0.0 ) {
largestep = up / 40. ;
} else {
largestep = c - > internal_to_interface ( desc . lower + largestep ) ;
}
2012-01-21 17:54:36 -05:00
_adjustment . set_lower ( lo ) ;
_adjustment . set_upper ( up ) ;
2014-11-30 18:33:11 -05:00
_adjustment . set_step_increment ( smallstep ) ;
_adjustment . set_page_increment ( largestep ) ;
_slider . set_default_value ( normal ) ;
2015-10-05 10:17:49 -04:00
2012-01-21 17:54:36 -05:00
_adjustment . signal_value_changed ( ) . connect ( sigc : : mem_fun ( * this , & Control : : slider_adjusted ) ) ;
2015-08-19 07:49:30 -04:00
// dup. currently timers are used :(
//c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
2012-01-21 17:54:36 -05:00
}
2012-01-20 13:02:48 -05:00
2015-08-19 07:49:30 -04:00
// yuck, do we really need to do this?
// according to c404374 this is only needed for send automation
timer_connection = Timers : : rapid_connect ( sigc : : mem_fun ( * this , & Control : : control_changed ) ) ;
2015-10-05 10:17:49 -04:00
2012-01-20 13:02:48 -05:00
control_changed ( ) ;
2012-03-21 10:13:48 -04:00
set_tooltip ( ) ;
2012-06-11 17:21:10 -04:00
/* We're providing our own PersistentTooltip */
set_no_tooltip_whatsoever ( _slider ) ;
2012-03-21 10:13:48 -04:00
}
2015-08-19 07:49:30 -04:00
ProcessorEntry : : Control : : ~ Control ( )
{
timer_connection . disconnect ( ) ;
}
2012-03-21 10:13:48 -04:00
void
ProcessorEntry : : Control : : set_tooltip ( )
{
boost : : shared_ptr < AutomationControl > c = _control . lock ( ) ;
if ( ! c ) {
return ;
}
work-around OSX loadlocale thread safety.
This is not a real fix; just a stop-gap for the worst offender.
iostream on OSX is not thread safe.
Sadly no crash report so far managed to catch the 2nd thread in action.
looks like the GUI thread is preempted, 2nd thread succeeds, and the
crash occurs later).
see also https://discussions.apple.com/thread/3479591
crash in
s << c->internal_to_user (c->get_value ());
ardour-4.1.335(5000,0x7fff777f5300) malloc: *** error for object 0x7fe2f3e06170: pointer being freed was not allocated
1 libsystem_c.dylib abort + 129
2 libsystem_malloc.dylib free + 428
3 libsystem_c.dylib __numeric_load_locale + 544
4 libsystem_c.dylib loadlocale + 216
5 libstdc++.6.dylib std::__convert_from_v(int* const&, char*, int, char const*, ...) + 193
6 libstdc++.6.dylib std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const + 193
7 libstdc++.6.dylib std::ostream& std::ostream::_M_insert<double>(double) + 221
8 ardour-4.1.335 ProcessorEntry::Control::set_tooltip() + 854 (processor_box.cc:578)
9 ardour-4.1.335 ProcessorEntry::Control::control_changed() + 446 (processor_box.cc:637)
10 ibpbd.dylib PBD::StandardTimer::on_elapsed()
2015-07-28 14:54:43 -04:00
char tmp [ 256 ] ;
2012-03-21 10:13:48 -04:00
if ( c - > toggled ( ) ) {
2015-07-28 21:34:27 -04:00
snprintf ( tmp , sizeof ( tmp ) , " %s: %s " , _name . c_str ( ) , c - > get_value ( ) > 0.5 ? _ ( " on " ) : _ ( " off " ) ) ;
2012-03-21 10:13:48 -04:00
} else {
2015-07-28 21:34:27 -04:00
snprintf ( tmp , sizeof ( tmp ) , " %s: %.2f " , _name . c_str ( ) , c - > internal_to_user ( c - > get_value ( ) ) ) ;
2012-03-21 10:13:48 -04:00
}
2013-01-21 13:18:42 -05:00
2015-10-15 05:24:15 -04:00
string sm = Gtkmm2ext : : markup_escape_text ( tmp ) ;
2013-01-21 13:18:42 -05:00
_slider_persistant_tooltip . set_tip ( sm ) ;
2015-01-05 00:32:14 -05:00
ARDOUR_UI_UTILS : : set_tooltip ( _button , sm ) ;
2012-01-20 13:02:48 -05:00
}
void
ProcessorEntry : : Control : : slider_adjusted ( )
{
2012-01-21 17:54:36 -05:00
if ( _ignore_ui_adjustment ) {
2012-01-20 13:02:48 -05:00
return ;
}
2015-10-05 10:17:49 -04:00
2012-01-20 13:02:48 -05:00
boost : : shared_ptr < AutomationControl > c = _control . lock ( ) ;
if ( ! c ) {
return ;
}
2012-01-21 11:38:45 -05:00
2016-01-02 04:58:23 -05:00
c - > set_value ( c - > interface_to_internal ( _adjustment . get_value ( ) ) , Controllable : : NoGroup ) ;
2012-06-11 17:21:10 -04:00
set_tooltip ( ) ;
2012-01-20 13:02:48 -05:00
}
2012-01-21 17:54:36 -05:00
void
ProcessorEntry : : Control : : button_clicked ( )
{
boost : : shared_ptr < AutomationControl > c = _control . lock ( ) ;
if ( ! c ) {
return ;
}
2012-02-07 12:43:55 -05:00
bool const n = _button . get_active ( ) ;
2016-01-02 04:58:23 -05:00
c - > set_value ( n ? 0 : 1 , Controllable : : NoGroup ) ;
2012-02-07 12:43:55 -05:00
_button . set_active ( ! n ) ;
2014-01-04 12:48:28 -05:00
set_tooltip ( ) ;
2012-01-21 17:54:36 -05:00
}
2015-10-14 06:38:44 -04:00
void
ProcessorEntry : : Control : : button_clicked_event ( GdkEventButton * ev )
{
( void ) ev ;
button_clicked ( ) ;
}
2012-01-20 13:02:48 -05:00
void
ProcessorEntry : : Control : : control_changed ( )
{
boost : : shared_ptr < AutomationControl > c = _control . lock ( ) ;
if ( ! c ) {
return ;
}
2012-01-21 17:54:36 -05:00
_ignore_ui_adjustment = true ;
2012-01-21 11:38:45 -05:00
2012-01-21 17:54:36 -05:00
if ( c - > toggled ( ) ) {
2012-01-21 11:38:45 -05:00
2012-02-07 12:43:55 -05:00
_button . set_active ( c - > get_value ( ) > 0.5 ) ;
2015-10-05 10:17:49 -04:00
2012-01-21 17:54:36 -05:00
} else {
2015-08-19 07:49:30 -04:00
// as long as rapid timers are used, only update the tooltip
// if the value has changed.
const double nval = c - > internal_to_interface ( c - > get_value ( ) ) ;
if ( _adjustment . get_value ( ) ! = nval ) {
_adjustment . set_value ( nval ) ;
set_tooltip ( ) ;
}
2012-01-21 17:54:36 -05:00
}
2015-10-05 10:17:49 -04:00
2012-01-21 17:54:36 -05:00
_ignore_ui_adjustment = false ;
2012-01-20 13:02:48 -05:00
}
void
ProcessorEntry : : Control : : add_state ( XMLNode * node ) const
{
XMLNode * c = new XMLNode ( X_ ( " Object " ) ) ;
c - > add_property ( X_ ( " id " ) , state_id ( ) ) ;
c - > add_property ( X_ ( " visible " ) , _visible ) ;
node - > add_child_nocopy ( * c ) ;
}
void
ProcessorEntry : : Control : : set_state ( XMLNode const * node )
{
XMLNode * n = GUIObjectState : : get_node ( node , state_id ( ) ) ;
if ( n ) {
2016-05-04 23:09:37 -04:00
XMLProperty const * p = n - > property ( X_ ( " visible " ) ) ;
2012-01-21 15:32:13 -05:00
set_visible ( p & & string_is_affirmative ( p - > value ( ) ) ) ;
2012-01-20 13:02:48 -05:00
} else {
2012-01-21 15:32:13 -05:00
set_visible ( false ) ;
2012-01-20 13:02:48 -05:00
}
}
void
2012-01-21 15:32:13 -05:00
ProcessorEntry : : Control : : set_visible ( bool v )
2012-01-20 13:02:48 -05:00
{
2012-01-21 15:32:13 -05:00
if ( v ) {
box . show ( ) ;
} else {
box . hide ( ) ;
}
2015-10-05 10:17:49 -04:00
2012-01-21 15:32:13 -05:00
_visible = v ;
2012-01-20 13:02:48 -05:00
}
/** Called when the Editor might have re-shown things that
we want hidden .
*/
void
ProcessorEntry : : Control : : hide_things ( )
{
if ( ! _visible ) {
box . hide ( ) ;
}
}
string
ProcessorEntry : : Control : : state_id ( ) const
{
boost : : shared_ptr < AutomationControl > c = _control . lock ( ) ;
assert ( c ) ;
return string_compose ( X_ ( " control %1 " ) , c - > id ( ) . to_s ( ) ) ;
}
2012-01-21 15:32:13 -05:00
PluginInsertProcessorEntry : : PluginInsertProcessorEntry ( ProcessorBox * b , boost : : shared_ptr < ARDOUR : : PluginInsert > p , Width w )
: ProcessorEntry ( b , p , w )
2011-01-31 20:50:49 -05:00
, _plugin_insert ( p )
{
2014-01-01 09:34:06 -05:00
p - > PluginIoReConfigure . connect (
2016-03-31 14:44:39 -04:00
_iomap_connection , invalidator ( * this ) , boost : : bind ( & PluginInsertProcessorEntry : : iomap_changed , this ) , gui_context ( )
) ;
p - > PluginMapChanged . connect (
_iomap_connection , invalidator ( * this ) , boost : : bind ( & PluginInsertProcessorEntry : : iomap_changed , this ) , gui_context ( )
2011-01-31 20:50:49 -05:00
) ;
2016-04-01 16:57:33 -04:00
p - > PluginConfigChanged . connect (
_iomap_connection , invalidator ( * this ) , boost : : bind ( & PluginInsertProcessorEntry : : iomap_changed , this ) , gui_context ( )
) ;
2011-01-31 20:50:49 -05:00
}
void
2016-03-31 14:44:39 -04:00
PluginInsertProcessorEntry : : iomap_changed ( )
2011-01-31 20:50:49 -05:00
{
2016-03-31 14:44:39 -04:00
_parent - > setup_routing_feeds ( ) ;
2016-04-01 16:57:33 -04:00
routing_icon . queue_draw ( ) ;
2016-04-03 19:27:33 -04:00
output_routing_icon . queue_draw ( ) ;
2011-01-31 20:50:49 -05:00
}
2011-02-09 21:44:56 -05:00
void
PluginInsertProcessorEntry : : hide_things ( )
{
2012-01-20 13:02:48 -05:00
ProcessorEntry : : hide_things ( ) ;
2011-02-09 21:44:56 -05:00
}
2015-04-22 14:22:35 -04:00
ProcessorEntry : : PortIcon : : PortIcon ( bool input ) {
_input = input ;
_ports = ARDOUR : : ChanCount ( ARDOUR : : DataType : : AUDIO , 1 ) ;
2015-01-02 09:44:54 -05:00
set_size_request ( - 1 , std : : max ( 2.f , rintf ( 2.f * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ) ;
2015-04-22 14:22:35 -04:00
}
2014-01-03 23:54:20 -05:00
bool
ProcessorEntry : : PortIcon : : on_expose_event ( GdkEventExpose * ev )
2011-01-31 20:50:49 -05:00
{
2014-01-03 23:54:20 -05:00
cairo_t * cr = gdk_cairo_create ( get_window ( ) - > gobj ( ) ) ;
2011-01-31 20:50:49 -05:00
2014-01-03 23:54:20 -05:00
cairo_rectangle ( cr , ev - > area . x , ev - > area . y , ev - > area . width , ev - > area . height ) ;
cairo_clip ( cr ) ;
2011-01-31 20:50:49 -05:00
2014-01-03 23:54:20 -05:00
Gtk : : Allocation a = get_allocation ( ) ;
double const width = a . get_width ( ) ;
double const height = a . get_height ( ) ;
Gdk : : Color const bg = get_style ( ) - > get_bg ( STATE_NORMAL ) ;
cairo_set_source_rgb ( cr , bg . get_red_p ( ) , bg . get_green_p ( ) , bg . get_blue_p ( ) ) ;
cairo_rectangle ( cr , 0 , 0 , width , height ) ;
cairo_fill ( cr ) ;
2015-01-02 09:44:54 -05:00
const double dx = rint ( max ( 2. , 2. * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ;
2016-04-19 07:21:09 -04:00
for ( uint32_t i = 0 ; i < _ports . n_total ( ) ; + + i ) {
set_routing_color ( cr , i < _ports . n_midi ( ) ) ;
const double x = ProcessorEntry : : RoutingIcon : : pin_x_pos ( i , width , _ports . n_total ( ) , 0 , false ) ;
cairo_rectangle ( cr , x - .5 - dx * .5 , 0 , 1 + dx , height ) ;
2014-01-09 13:18:19 -05:00
cairo_fill ( cr ) ;
2011-01-31 20:50:49 -05:00
}
2014-01-03 23:54:20 -05:00
cairo_destroy ( cr ) ;
return true ;
2011-01-31 20:50:49 -05:00
}
2016-04-03 19:27:33 -04:00
ProcessorEntry : : RoutingIcon : : RoutingIcon ( bool input )
2016-04-16 15:28:37 -04:00
: _fed_by ( false )
2016-04-03 19:27:33 -04:00
, _input ( input )
2016-03-31 14:44:39 -04:00
{
2016-04-16 15:28:37 -04:00
set_terminal ( false ) ;
}
void
ProcessorEntry : : RoutingIcon : : set_terminal ( bool b ) {
_terminal = b ;
int h = std : : max ( 8.f , rintf ( 8.f * sqrt ( UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ) ;
if ( _terminal ) {
h + = std : : max ( 4.f , rintf ( 4.f * sqrt ( UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ) ;
2016-04-03 19:27:33 -04:00
}
2016-04-16 15:28:37 -04:00
set_size_request ( - 1 , h ) ;
2016-03-31 14:44:39 -04:00
}
void
ProcessorEntry : : RoutingIcon : : set (
const ARDOUR : : ChanCount & in ,
const ARDOUR : : ChanCount & out ,
const ARDOUR : : ChanCount & sinks ,
const ARDOUR : : ChanCount & sources ,
const ARDOUR : : ChanMapping & in_map ,
2016-04-07 12:36:04 -04:00
const ARDOUR : : ChanMapping & out_map ,
const ARDOUR : : ChanMapping & thru_map )
2016-03-31 14:44:39 -04:00
{
2016-04-07 12:36:04 -04:00
_in = in ;
_out = out ;
_sources = sources ;
_sinks = sinks ;
_in_map = in_map ;
_out_map = out_map ;
_thru_map = thru_map ;
2016-03-31 14:44:39 -04:00
}
bool
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : in_identity ( ) const {
if ( _thru_map . n_total ( ) > 0 ) {
return false ;
}
2016-04-02 08:51:32 -04:00
if ( ! _in_map . is_monotonic ( ) | | ! _in_map . is_identity ( ) ) {
2016-03-31 14:44:39 -04:00
return false ;
}
2016-04-08 09:53:32 -04:00
if ( _in_map . n_total ( ) ! = _sinks . n_total ( ) | | _in . n_total ( ) ! = _sinks . n_total ( ) ) {
2016-03-31 14:44:39 -04:00
return false ;
}
return true ;
}
2016-04-03 19:27:33 -04:00
bool
ProcessorEntry : : RoutingIcon : : out_identity ( ) const {
2016-04-16 15:28:37 -04:00
if ( _thru_map . n_total ( ) > 0 ) {
// TODO skip if trhu is not connected to any of next's inputs
return false ;
}
2016-04-03 19:27:33 -04:00
if ( ! _out_map . is_monotonic ( ) | | ! _out_map . is_identity ( ) ) {
return false ;
}
2016-04-08 09:53:32 -04:00
if ( _out_map . n_total ( ) ! = _sources . n_total ( ) | | _out . n_total ( ) ! = _sources . n_total ( ) ) {
2016-04-03 19:27:33 -04:00
return false ;
}
2016-04-16 15:28:37 -04:00
return true ;
}
bool
ProcessorEntry : : RoutingIcon : : can_coalesce ( ) const {
2016-04-08 09:53:32 -04:00
if ( _thru_map . n_total ( ) > 0 ) {
2016-04-07 12:36:04 -04:00
return false ;
}
2016-04-16 15:28:37 -04:00
if ( _fed_by & & _f_out ! = _f_sources ) {
return false ;
}
2016-05-24 12:18:26 -04:00
if ( _fed_by & & ! _f_out_map . is_identity ( ) & & ! _in_map . is_identity ( ) ) {
return false ;
}
2016-04-16 15:28:37 -04:00
if ( _input & & _sinks = = _in & & ( ! _fed_by | | _f_out = = _in ) ) {
return true ;
}
return false ;
2016-04-03 19:27:33 -04:00
}
2016-03-31 14:44:39 -04:00
void
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : set_fed_by (
2016-03-31 14:44:39 -04:00
const ARDOUR : : ChanCount & out ,
const ARDOUR : : ChanCount & sources ,
2016-04-07 12:36:04 -04:00
const ARDOUR : : ChanMapping & out_map ,
const ARDOUR : : ChanMapping & thru_map )
2016-03-31 14:44:39 -04:00
{
2016-04-07 12:36:04 -04:00
_f_out = out ;
_f_sources = sources ;
_f_out_map = out_map ;
_f_thru_map = thru_map ;
2016-04-16 15:28:37 -04:00
_fed_by = true ;
}
void
ProcessorEntry : : RoutingIcon : : set_feeding (
const ARDOUR : : ChanCount & in ,
const ARDOUR : : ChanCount & sinks ,
const ARDOUR : : ChanMapping & in_map ,
const ARDOUR : : ChanMapping & thru_map )
{
_i_in = in ;
_i_sinks = sinks ;
_i_in_map = in_map ;
_i_thru_map = thru_map ;
_feeding = true ;
2016-03-31 14:44:39 -04:00
}
double
ProcessorEntry : : RoutingIcon : : pin_x_pos ( uint32_t i , double width , uint32_t n_total , uint32_t n_midi , bool midi )
{
if ( ! midi ) { i + = n_midi ; }
if ( n_total = = 1 ) {
assert ( i = = 0 ) ;
return rint ( width * .5 ) + .5 ;
}
2016-04-19 07:21:09 -04:00
return rint ( width * ( .15 + .7 * i / ( n_total - 1 ) ) ) + .5 ;
2016-03-31 14:44:39 -04:00
}
2016-04-03 19:27:33 -04:00
void
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : draw_gnd ( cairo_t * cr , double x0 , double y0 , double height , bool midi )
2016-04-03 19:27:33 -04:00
{
2016-04-16 15:28:37 -04:00
const double dx = 1 + rint ( max ( 2. , 2. * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ;
const double y1 = rint ( height * .66 ) + .5 ;
2016-04-03 19:27:33 -04:00
2016-04-16 15:28:37 -04:00
cairo_save ( cr ) ;
cairo_translate ( cr , x0 , y0 ) ;
cairo_move_to ( cr , 0 , height ) ;
cairo_line_to ( cr , 0 , y1 ) ;
cairo_move_to ( cr , 0 - dx , y1 ) ;
cairo_line_to ( cr , 0 + dx , y1 ) ;
2016-04-03 19:27:33 -04:00
set_routing_color ( cr , midi ) ;
2016-04-16 15:28:37 -04:00
cairo_set_line_width ( cr , 1.0 ) ;
2016-04-03 19:27:33 -04:00
cairo_stroke ( cr ) ;
2016-04-16 15:28:37 -04:00
cairo_restore ( cr ) ;
2016-04-03 19:27:33 -04:00
}
2016-03-31 14:44:39 -04:00
void
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : draw_sidechain ( cairo_t * cr , double x0 , double y0 , double height , bool midi )
2016-03-31 14:44:39 -04:00
{
const double dx = 1 + rint ( max ( 2. , 2. * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ;
2016-04-16 15:28:37 -04:00
const double y1 = rint ( height * .5 ) - .5 ;
2016-03-31 14:44:39 -04:00
2016-04-16 15:28:37 -04:00
cairo_save ( cr ) ;
cairo_translate ( cr , x0 , y0 ) ;
cairo_move_to ( cr , 0 - dx , height ) ;
cairo_line_to ( cr , 0 , y1 ) ;
cairo_line_to ( cr , 0 + dx , height ) ;
cairo_close_path ( cr ) ;
2016-03-31 14:44:39 -04:00
set_routing_color ( cr , midi ) ;
2016-04-16 15:28:37 -04:00
cairo_fill ( cr ) ;
cairo_restore ( cr ) ;
2016-03-31 14:44:39 -04:00
}
2016-04-02 21:11:43 -04:00
void
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : draw_thru_src ( cairo_t * cr , double x0 , double y0 , double height , bool midi )
2016-04-02 21:11:43 -04:00
{
2016-04-19 07:31:41 -04:00
const double rad = 1 ;
2016-04-19 07:21:09 -04:00
const double y1 = height - rad - 1.5 ;
2016-04-02 21:11:43 -04:00
2016-04-19 07:21:09 -04:00
cairo_arc ( cr , x0 , y0 + y1 , rad , 0 , 2. * M_PI ) ;
cairo_move_to ( cr , x0 , y0 + height - 1.5 ) ;
cairo_line_to ( cr , x0 , y0 + height ) ;
2016-04-02 21:11:43 -04:00
set_routing_color ( cr , midi ) ;
2016-04-16 15:28:37 -04:00
cairo_set_line_width ( cr , 1.0 ) ;
cairo_stroke ( cr ) ;
2016-04-02 21:11:43 -04:00
}
2016-04-07 12:36:04 -04:00
void
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : draw_thru_sink ( cairo_t * cr , double x0 , double y0 , double height , bool midi )
2016-04-07 12:36:04 -04:00
{
2016-04-19 07:31:41 -04:00
const double rad = 1 ;
2016-04-19 07:21:09 -04:00
const double y1 = rad + 1 ;
2016-04-07 12:36:04 -04:00
2016-04-19 07:21:09 -04:00
cairo_arc ( cr , x0 , y0 + y1 , rad , 0 , 2. * M_PI ) ;
cairo_move_to ( cr , x0 , y0 ) ;
cairo_line_to ( cr , x0 , y0 + 1 ) ;
2016-04-07 12:36:04 -04:00
set_routing_color ( cr , midi ) ;
cairo_set_line_width ( cr , 1.0 ) ;
2016-04-12 12:38:28 -04:00
cairo_stroke ( cr ) ;
2016-04-07 12:36:04 -04:00
}
2016-03-31 14:44:39 -04:00
void
ProcessorEntry : : RoutingIcon : : draw_connection ( cairo_t * cr , double x0 , double x1 , double y0 , double y1 , bool midi , bool dashed )
{
double bz = abs ( y1 - y0 ) ;
cairo_move_to ( cr , x0 , y0 ) ;
cairo_curve_to ( cr , x0 , y0 + bz , x1 , y1 - bz , x1 , y1 ) ;
cairo_set_line_width ( cr , 1.0 ) ;
cairo_set_line_cap ( cr , CAIRO_LINE_CAP_ROUND ) ;
cairo_set_source_rgb ( cr , 1 , 0 , 0 ) ;
if ( dashed ) {
const double dashes [ ] = { 2 , 3 } ;
cairo_set_dash ( cr , dashes , 2 , 0 ) ;
}
set_routing_color ( cr , midi ) ;
cairo_stroke ( cr ) ;
if ( dashed ) {
cairo_set_dash ( cr , 0 , 0 , 0 ) ;
}
}
2011-01-31 20:50:49 -05:00
bool
2014-01-03 23:54:20 -05:00
ProcessorEntry : : RoutingIcon : : on_expose_event ( GdkEventExpose * ev )
2011-01-31 20:50:49 -05:00
{
cairo_t * cr = gdk_cairo_create ( get_window ( ) - > gobj ( ) ) ;
2013-07-16 16:18:51 -04:00
cairo_rectangle ( cr , ev - > area . x , ev - > area . y , ev - > area . width , ev - > area . height ) ;
cairo_clip ( cr ) ;
2013-07-18 05:27:21 -04:00
cairo_set_line_cap ( cr , CAIRO_LINE_CAP_ROUND ) ;
2011-01-31 20:50:49 -05:00
2013-07-16 16:18:51 -04:00
Gtk : : Allocation a = get_allocation ( ) ;
double const width = a . get_width ( ) ;
double const height = a . get_height ( ) ;
2011-01-31 20:50:49 -05:00
Gdk : : Color const bg = get_style ( ) - > get_bg ( STATE_NORMAL ) ;
cairo_set_source_rgb ( cr , bg . get_red_p ( ) , bg . get_green_p ( ) , bg . get_blue_p ( ) ) ;
2011-06-01 13:00:29 -04:00
2011-01-31 20:50:49 -05:00
cairo_rectangle ( cr , 0 , 0 , width , height ) ;
cairo_fill ( cr ) ;
2016-04-03 19:27:33 -04:00
if ( _input ) {
2016-04-16 15:28:37 -04:00
if ( can_coalesce ( ) ) {
expose_coalesced_input_map ( cr , width , height ) ;
} else {
expose_input_map ( cr , width , height ) ;
}
2016-04-03 19:27:33 -04:00
} else {
expose_output_map ( cr , width , height ) ;
}
2014-01-01 09:34:06 -05:00
2016-03-31 14:44:39 -04:00
cairo_destroy ( cr ) ;
return true ;
}
void
2016-04-16 15:28:37 -04:00
ProcessorEntry : : RoutingIcon : : expose_coalesced_input_map ( cairo_t * cr , const double width , const double height )
2016-03-31 14:44:39 -04:00
{
const uint32_t pc_in = _sinks . n_total ( ) ;
const uint32_t pc_in_midi = _sinks . n_midi ( ) ;
for ( uint32_t i = 0 ; i < pc_in ; + + i ) {
const bool is_midi = i < pc_in_midi ;
bool valid_in ;
uint32_t pn = is_midi ? i : i - pc_in_midi ;
2016-04-02 21:11:43 -04:00
DataType dt = is_midi ? DataType : : MIDI : DataType : : AUDIO ;
uint32_t idx = _in_map . get ( dt , pn , & valid_in ) ;
2016-03-31 14:44:39 -04:00
if ( ! valid_in ) {
2016-04-03 19:27:33 -04:00
double x = pin_x_pos ( i , width , pc_in , 0 , is_midi ) ;
2016-04-16 15:28:37 -04:00
draw_gnd ( cr , x , 0 , height , is_midi ) ;
2016-03-31 14:44:39 -04:00
continue ;
2015-08-04 12:42:27 -04:00
}
2016-04-02 21:11:43 -04:00
if ( idx > = _in . get ( dt ) ) {
// side-chain, probably
2016-04-03 19:27:33 -04:00
double x = pin_x_pos ( i , width , pc_in , 0 , is_midi ) ;
2016-04-16 15:28:37 -04:00
draw_sidechain ( cr , x , 0 , height , is_midi ) ;
2016-04-02 21:11:43 -04:00
continue ;
}
2016-03-31 14:44:39 -04:00
double c_x0 ;
double c_x1 = pin_x_pos ( i , width , pc_in , 0 , false ) ;
2016-04-16 15:28:37 -04:00
if ( _fed_by ) {
2016-03-31 14:44:39 -04:00
bool valid_src ;
2016-04-02 21:11:43 -04:00
uint32_t src = _f_out_map . get_src ( dt , idx , & valid_src ) ;
2016-03-31 14:44:39 -04:00
if ( ! valid_src ) {
2016-04-01 21:20:43 -04:00
double x = pin_x_pos ( i , width , pc_in , 0 , false ) ;
2016-04-07 12:36:04 -04:00
bool valid_thru ;
_f_thru_map . get ( dt , idx , & valid_thru ) ;
if ( valid_thru ) {
2016-04-16 15:28:37 -04:00
draw_thru_src ( cr , x , 0 , height , is_midi ) ;
2016-04-07 12:36:04 -04:00
} else {
2016-04-16 15:28:37 -04:00
draw_gnd ( cr , x , 0 , height , is_midi ) ;
2016-04-07 12:36:04 -04:00
}
2016-03-31 14:44:39 -04:00
continue ;
}
2016-04-02 08:51:32 -04:00
c_x0 = pin_x_pos ( src , width , _f_sources . n_total ( ) , _f_sources . n_midi ( ) , is_midi ) ;
2015-08-04 12:42:27 -04:00
} else {
2016-03-31 14:44:39 -04:00
c_x0 = pin_x_pos ( idx , width , _in . n_total ( ) , _in . n_midi ( ) , is_midi ) ;
2015-08-04 12:42:27 -04:00
}
2016-03-31 14:44:39 -04:00
draw_connection ( cr , c_x0 , c_x1 , 0 , height , is_midi ) ;
2013-12-30 09:55:17 -05:00
}
2011-01-31 20:50:49 -05:00
}
2016-04-16 15:28:37 -04:00
void
ProcessorEntry : : RoutingIcon : : expose_input_map ( cairo_t * cr , const double width , const double height )
{
const uint32_t n_in = _in . n_total ( ) ;
const uint32_t n_in_midi = _in . n_midi ( ) ;
const uint32_t pc_in = _sinks . n_total ( ) ;
const uint32_t pc_in_midi = _sinks . n_midi ( ) ;
// draw inputs to this
for ( uint32_t i = 0 ; i < pc_in ; + + i ) {
const bool is_midi = i < pc_in_midi ;
bool valid_in ;
uint32_t pn = is_midi ? i : i - pc_in_midi ;
DataType dt = is_midi ? DataType : : MIDI : DataType : : AUDIO ;
uint32_t idx = _in_map . get ( dt , pn , & valid_in ) ;
// check if it's fed
bool valid_src = true ;
if ( valid_in & & idx < _in . get ( dt ) & & _fed_by ) {
bool valid_out ;
bool valid_thru ;
_f_out_map . get_src ( dt , idx , & valid_out ) ;
_f_thru_map . get ( dt , idx , & valid_thru ) ;
if ( ! valid_out & & ! valid_thru ) {
valid_src = false ;
}
}
if ( ! valid_in | | ! valid_src ) {
double x = pin_x_pos ( i , width , pc_in , 0 , is_midi ) ;
draw_gnd ( cr , x , 0 , height , is_midi ) ;
continue ;
}
if ( idx > = _in . get ( dt ) ) {
// side-chain, probably
double x = pin_x_pos ( i , width , pc_in , 0 , is_midi ) ;
draw_sidechain ( cr , x , 0 , height , is_midi ) ;
continue ;
}
double c_x1 = pin_x_pos ( i , width , pc_in , 0 , false ) ;
double c_x0 = pin_x_pos ( idx , width , n_in , n_in_midi , is_midi ) ;
draw_connection ( cr , c_x0 , c_x1 , 0 , height , is_midi ) ;
}
// draw reverse thru
for ( uint32_t i = 0 ; i < n_in ; + + i ) {
const bool is_midi = i < n_in_midi ;
bool valid_thru ;
uint32_t pn = is_midi ? i : i - n_in_midi ;
DataType dt = is_midi ? DataType : : MIDI : DataType : : AUDIO ;
2016-04-16 16:15:34 -04:00
_thru_map . get_src ( dt , pn , & valid_thru ) ;
2016-04-16 15:28:37 -04:00
if ( ! valid_thru ) {
continue ;
}
double x = pin_x_pos ( i , width , n_in , 0 , is_midi ) ;
draw_thru_sink ( cr , x , 0 , height , is_midi ) ;
}
}
2016-04-03 19:27:33 -04:00
void
ProcessorEntry : : RoutingIcon : : expose_output_map ( cairo_t * cr , const double width , const double height )
{
2016-04-16 15:28:37 -04:00
int dh = std : : max ( 4.f , rintf ( 4.f * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ;
double ht = _terminal ? height - dh : height ;
// draw outputs of this
2016-04-03 19:27:33 -04:00
const uint32_t pc_out = _sources . n_total ( ) ;
const uint32_t pc_out_midi = _sources . n_midi ( ) ;
const uint32_t n_out = _out . n_total ( ) ;
const uint32_t n_out_midi = _out . n_midi ( ) ;
for ( uint32_t i = 0 ; i < pc_out ; + + i ) {
const bool is_midi = i < pc_out_midi ;
bool valid_out ;
uint32_t pn = is_midi ? i : i - pc_out_midi ;
DataType dt = is_midi ? DataType : : MIDI : DataType : : AUDIO ;
uint32_t idx = _out_map . get ( dt , pn , & valid_out ) ;
if ( ! valid_out ) {
continue ;
}
2016-04-16 15:28:37 -04:00
// skip connections that are not used in the next's input
if ( _feeding ) {
bool valid_thru , valid_sink ;
_i_in_map . get_src ( dt , idx , & valid_sink ) ;
_i_thru_map . get_src ( dt , idx , & valid_thru ) ;
if ( ! valid_thru & & ! valid_sink ) {
2016-04-19 11:31:00 -04:00
if ( ! is_midi | | i ! = 0 ) { // special case midi-bypass
continue ;
}
2016-04-16 15:28:37 -04:00
}
}
2016-04-03 19:27:33 -04:00
double c_x0 = pin_x_pos ( i , width , pc_out , 0 , false ) ;
double c_x1 = pin_x_pos ( idx , width , n_out , n_out_midi , is_midi ) ;
2016-04-16 15:28:37 -04:00
draw_connection ( cr , c_x0 , c_x1 , 0 , ht , is_midi ) ;
2016-04-03 19:27:33 -04:00
}
for ( uint32_t i = 0 ; i < n_out ; + + i ) {
const bool is_midi = i < n_out_midi ;
uint32_t pn = is_midi ? i : i - n_out_midi ;
DataType dt = is_midi ? DataType : : MIDI : DataType : : AUDIO ;
2016-04-16 15:28:37 -04:00
double x = pin_x_pos ( i , width , n_out , 0 , is_midi ) ;
if ( ! _terminal ) {
2016-04-19 07:21:09 -04:00
bool valid_thru_f = false ;
// skip connections that are not used in the next's input
2016-04-16 15:28:37 -04:00
if ( _feeding ) {
bool valid_sink ;
_i_in_map . get_src ( dt , pn , & valid_sink ) ;
2016-04-19 07:21:09 -04:00
_i_thru_map . get_src ( dt , pn , & valid_thru_f ) ;
if ( ! valid_thru_f & & ! valid_sink ) {
2016-04-19 11:31:00 -04:00
if ( ! is_midi | | i ! = 0 ) { // special case midi-bypass
continue ;
}
2016-04-16 15:28:37 -04:00
}
}
2016-04-19 07:21:09 -04:00
bool valid_src ;
_out_map . get_src ( dt , pn , & valid_src ) ;
if ( ! valid_src ) {
bool valid_thru ;
uint32_t idx = _thru_map . get ( dt , pn , & valid_thru ) ;
if ( valid_thru ) {
if ( idx > = _in . get ( dt ) ) {
draw_sidechain ( cr , x , 0 , height , is_midi ) ;
} else {
draw_thru_src ( cr , x , 0 , height , is_midi ) ;
}
} else if ( valid_thru_f ) {
// gnd is part of input, unless it's a thru input
// (also only true if !coalesced into one small display)
draw_gnd ( cr , x , 0 , height , is_midi ) ;
}
2016-04-07 12:36:04 -04:00
}
2016-04-16 15:28:37 -04:00
} else {
// terminal node, add arrows
bool valid_src ;
_out_map . get_src ( dt , pn , & valid_src ) ;
if ( ! valid_src ) {
bool valid_thru ;
uint32_t idx = _thru_map . get ( dt , pn , & valid_thru ) ;
if ( valid_thru ) {
if ( idx > = _in . get ( dt ) ) {
draw_sidechain ( cr , x , 0 , height - dh , is_midi ) ;
} else {
draw_thru_src ( cr , x , 0 , height - dh , is_midi ) ;
}
} else {
draw_gnd ( cr , x , 0 , height - dh , is_midi ) ;
}
}
set_routing_color ( cr , is_midi ) ;
cairo_set_line_width ( cr , 1.0 ) ;
cairo_move_to ( cr , x , height - dh ) ;
cairo_line_to ( cr , x , height - 2 ) ;
cairo_stroke ( cr ) ;
const double ar = dh - 1 ;
cairo_move_to ( cr , x - ar , height - ar ) ;
cairo_line_to ( cr , x , height - .5 ) ;
cairo_line_to ( cr , x + ar , height - ar ) ;
cairo_line_to ( cr , x , height - ar * .5 ) ;
cairo_close_path ( cr ) ;
cairo_fill_preserve ( cr ) ;
cairo_stroke ( cr ) ;
2016-04-03 19:27:33 -04:00
}
}
}
2016-03-14 06:48:22 -04:00
ProcessorEntry : : PluginDisplay : : PluginDisplay ( boost : : shared_ptr < ARDOUR : : Plugin > p , uint32_t max_height )
: _plug ( p )
2016-03-14 11:44:51 -04:00
, _surf ( 0 )
2016-03-14 06:48:22 -04:00
, _max_height ( max_height )
, _cur_height ( 1 )
2016-03-14 17:32:21 -04:00
, _scroll ( false )
2016-03-14 06:48:22 -04:00
{
set_name ( " processor prefader " ) ;
_plug - > QueueDraw . connect ( _qdraw_connection , invalidator ( * this ) ,
boost : : bind ( & Gtk : : Widget : : queue_draw , this ) , gui_context ( ) ) ;
}
2016-03-14 11:44:51 -04:00
ProcessorEntry : : PluginDisplay : : ~ PluginDisplay ( )
{
if ( _surf ) {
cairo_surface_destroy ( _surf ) ;
}
}
2016-03-14 06:48:22 -04:00
void
ProcessorEntry : : PluginDisplay : : on_size_request ( Gtk : : Requisition * req )
{
req - > width = 56 ;
req - > height = _cur_height ;
}
2016-03-18 16:33:45 -04:00
void
ProcessorEntry : : PluginDisplay : : update_height_alloc ( uint32_t inline_height )
{
2016-03-14 17:32:21 -04:00
/* work-around scroll-bar + aspect ratio
* show inline - view - > height changes - > scrollbar gets added
* - > width changes - > inline - view , fixed aspect ratio - > height changes
* - > scroll bar is removed [ - > width changes ; repeat ]
*/
2016-03-18 16:33:45 -04:00
uint32_t shm = std : : min ( _max_height , inline_height ) ;
2016-03-14 17:32:21 -04:00
bool sc = false ;
Gtk : : Container * pr = get_parent ( ) ;
for ( uint32_t i = 0 ; i < 4 & & pr ; + + i ) {
// VBox, EventBox, ViewPort, ScrolledWindow
pr = pr - > get_parent ( ) ;
}
Gtk : : ScrolledWindow * sw = dynamic_cast < Gtk : : ScrolledWindow * > ( pr ) ;
if ( sw ) {
const Gtk : : VScrollbar * vsb = sw - > get_vscrollbar ( ) ;
sc = vsb & & vsb - > is_visible ( ) ;
}
if ( shm ! = _cur_height ) {
if ( _scroll = = sc | | _cur_height < shm ) {
queue_resize ( ) ;
}
_cur_height = shm ;
}
_scroll = sc ;
2016-03-18 16:33:45 -04:00
}
2016-03-14 17:32:21 -04:00
2016-03-18 16:33:45 -04:00
uint32_t
ProcessorEntry : : PluginDisplay : : render_inline ( cairo_t * cr , uint32_t width )
{
Plugin : : Display_Image_Surface * dis = _plug - > render_inline_display ( width , _max_height ) ;
if ( ! dis ) {
return 0 ;
}
2016-03-14 17:32:21 -04:00
/* allocate a local image-surface,
* We cannot re - use the data via cairo_image_surface_create_for_data ( ) ,
* since pixman keeps a reference to it .
* we ' d need to hand over the data and ha cairo_surface_destroy to free it .
* it might be possible to work around via cairo_surface_set_user_data ( ) .
*/
2016-03-14 11:44:51 -04:00
if ( ! _surf
2016-03-14 17:32:21 -04:00
| | dis - > width ! = cairo_image_surface_get_width ( _surf )
| | dis - > height ! = cairo_image_surface_get_height ( _surf )
) {
2016-03-14 11:44:51 -04:00
if ( _surf ) {
cairo_surface_destroy ( _surf ) ;
}
2016-03-14 17:32:21 -04:00
_surf = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32 , dis - > width , dis - > height ) ;
}
if ( cairo_image_surface_get_stride ( _surf ) = = dis - > stride ) {
memcpy ( cairo_image_surface_get_data ( _surf ) , dis - > data , dis - > stride * dis - > height ) ;
2016-03-14 11:44:51 -04:00
} else {
2016-03-14 17:32:21 -04:00
unsigned char * src = dis - > data ;
unsigned char * dst = cairo_image_surface_get_data ( _surf ) ;
const int dst_stride = cairo_image_surface_get_stride ( _surf ) ;
2016-03-14 19:27:13 -04:00
for ( int y = 0 ; y < dis - > height ; + + y ) {
2016-03-14 17:32:21 -04:00
memcpy ( dst , src , dis - > width * 4 /*ARGB32*/ ) ;
src + = dis - > stride ;
dst + = dst_stride ;
}
2016-03-14 11:44:51 -04:00
}
2016-03-18 16:33:45 -04:00
2016-03-14 17:32:21 -04:00
cairo_surface_mark_dirty ( _surf ) ;
2016-03-18 16:33:45 -04:00
const double xc = floor ( ( width - dis - > width ) * .5 ) ;
cairo_set_source_surface ( cr , _surf , xc , 0 ) ;
cairo_paint ( cr ) ;
return dis - > height ;
}
bool
ProcessorEntry : : PluginDisplay : : on_expose_event ( GdkEventExpose * ev )
{
Gtk : : Allocation a = get_allocation ( ) ;
double const width = a . get_width ( ) ;
double const height = a . get_height ( ) ;
2016-03-14 11:44:51 -04:00
2016-03-14 06:48:22 -04:00
cairo_t * cr = gdk_cairo_create ( get_window ( ) - > gobj ( ) ) ;
cairo_rectangle ( cr , ev - > area . x , ev - > area . y , ev - > area . width , ev - > area . height ) ;
cairo_clip ( cr ) ;
Gdk : : Color const bg = get_style ( ) - > get_bg ( STATE_NORMAL ) ;
cairo_set_source_rgb ( cr , bg . get_red_p ( ) , bg . get_green_p ( ) , bg . get_blue_p ( ) ) ;
cairo_rectangle ( cr , 0 , 0 , width , height ) ;
cairo_fill ( cr ) ;
2016-03-14 11:44:51 -04:00
cairo_save ( cr ) ;
cairo_set_operator ( cr , CAIRO_OPERATOR_SOURCE ) ;
Gtkmm2ext : : rounded_rectangle ( cr , .5 , - 1.5 , width - 1 , height + 1 , 7 ) ;
cairo_clip ( cr ) ;
2016-03-18 16:33:45 -04:00
cairo_set_operator ( cr , CAIRO_OPERATOR_OVER ) ;
2016-03-14 11:44:51 -04:00
2016-03-18 16:33:45 -04:00
uint32_t ht = render_inline ( cr , width ) ;
2016-03-14 11:44:51 -04:00
cairo_restore ( cr ) ;
2016-03-14 06:48:22 -04:00
2016-03-18 16:33:45 -04:00
if ( ht = = 0 ) {
hide ( ) ;
if ( _cur_height ! = 1 ) {
_cur_height = 1 ;
queue_resize ( ) ;
}
cairo_destroy ( cr ) ;
return true ;
} else {
update_height_alloc ( ht ) ;
}
2016-03-14 06:48:22 -04:00
bool failed = false ;
std : : string name = get_name ( ) ;
ArdourCanvas : : Color fill_color = UIConfiguration : : instance ( ) . color ( string_compose ( " %1: fill active " , name ) , & failed ) ;
Gtkmm2ext : : rounded_rectangle ( cr , .5 , - 1.5 , width - 1 , height + 1 , 7 ) ;
cairo_set_operator ( cr , CAIRO_OPERATOR_OVER ) ;
cairo_set_line_width ( cr , 1.0 ) ;
ArdourCanvas : : set_source_rgb_a ( cr , fill_color , 1.0 ) ;
cairo_stroke ( cr ) ;
cairo_destroy ( cr ) ;
return true ;
}
2016-03-18 16:33:45 -04:00
ProcessorEntry : : LuaPluginDisplay : : LuaPluginDisplay ( boost : : shared_ptr < ARDOUR : : LuaProc > p , uint32_t max_height )
: PluginDisplay ( p , max_height )
, _luaproc ( p )
, _lua_render_inline ( 0 )
{
p - > setup_lua_inline_gui ( & lua_gui ) ;
lua_State * LG = lua_gui . getState ( ) ;
LuaInstance : : bind_cairo ( LG ) ;
luabridge : : LuaRef lua_render = luabridge : : getGlobal ( LG , " render_inline " ) ;
assert ( lua_render . isFunction ( ) ) ;
_lua_render_inline = new luabridge : : LuaRef ( lua_render ) ;
}
ProcessorEntry : : LuaPluginDisplay : : ~ LuaPluginDisplay ( )
{
delete ( _lua_render_inline ) ;
}
uint32_t
ProcessorEntry : : LuaPluginDisplay : : render_inline ( cairo_t * cr , uint32_t width )
{
Cairo : : Context ctx ( cr ) ;
2016-03-21 16:39:11 -04:00
try {
luabridge : : LuaRef rv = ( * _lua_render_inline ) ( ( Cairo : : Context * ) & ctx , width , _max_height ) ;
if ( rv . isTable ( ) ) {
uint32_t h = rv [ 2 ] ;
return h ;
}
} catch ( luabridge : : LuaException const & e ) {
2016-05-20 17:15:58 -04:00
# ifndef NDEBUG
cerr < < " LuaException: " < < e . what ( ) < < endl ;
# endif
2016-03-18 16:33:45 -04:00
}
return 0 ;
}
2015-12-21 22:15:04 -05:00
static std : : list < Gtk : : TargetEntry > drop_targets ( )
{
std : : list < Gtk : : TargetEntry > tmp ;
2016-01-01 07:24:23 -05:00
tmp . push_back ( Gtk : : TargetEntry ( " processor " ) ) ; // from processor-box to processor-box
tmp . push_back ( Gtk : : TargetEntry ( " PluginInfoPtr " ) ) ; // from plugin-manager
2016-05-06 08:55:36 -04:00
tmp . push_back ( Gtk : : TargetEntry ( " PluginFavoritePtr " ) ) ; // from sidebar
2015-12-21 22:15:04 -05:00
return tmp ;
}
2016-01-01 07:24:23 -05:00
static std : : list < Gtk : : TargetEntry > drag_targets ( )
2015-12-30 06:15:25 -05:00
{
std : : list < Gtk : : TargetEntry > tmp ;
2016-01-01 07:24:23 -05:00
tmp . push_back ( Gtk : : TargetEntry ( " PluginPresetPtr " ) ) ; // to sidebar (optional preset)
tmp . push_back ( Gtk : : TargetEntry ( " processor " ) ) ; // to processor-box (copy)
return tmp ;
}
static std : : list < Gtk : : TargetEntry > drag_targets_noplugin ( )
{
std : : list < Gtk : : TargetEntry > tmp ;
tmp . push_back ( Gtk : : TargetEntry ( " processor " ) ) ; // to processor box (sends, faders re-order)
2015-12-30 06:15:25 -05:00
return tmp ;
}
2009-12-17 13:24:23 -05:00
ProcessorBox : : ProcessorBox ( ARDOUR : : Session * sess , boost : : function < PluginSelector * ( ) > get_plugin_selector ,
2011-11-15 14:33:09 -05:00
RouteProcessorSelection & rsel , MixerStrip * parent , bool owner_is_mixer )
2009-12-17 13:24:23 -05:00
: _parent_strip ( parent )
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
, _owner_is_mixer ( owner_is_mixer )
2009-11-30 08:13:57 -05:00
, ab_direction ( true )
2009-10-22 13:17:34 -04:00
, _get_plugin_selector ( get_plugin_selector )
2011-10-19 12:53:36 -04:00
, _placement ( - 1 )
2012-01-07 12:10:18 -05:00
, _visible_prefader_processors ( 0 )
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
, _rr_selection ( rsel )
2015-12-21 22:15:04 -05:00
, processor_display ( drop_targets ( ) )
2013-01-16 21:35:06 -05:00
, _redisplay_pending ( false )
2007-06-27 16:23:48 -04:00
{
2009-12-17 13:24:23 -05:00
set_session ( sess ) ;
2016-03-15 12:40:53 -04:00
/* ProcessorBox actions and bindings created statically by call to
* ProcessorBox : : register_actions ( ) , made by ARDOUR_UI so that actions
* are available for context menus .
*/
processor_display . set_data ( " ardour-bindings " , bindings ) ;
2007-06-27 16:23:48 -04:00
_width = Wide ;
processor_menu = 0 ;
no_processor_redisplay = false ;
processor_scroller . set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
processor_scroller . add ( processor_display ) ;
2009-11-25 09:37:20 -05:00
pack_start ( processor_scroller , true , true ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-11-27 12:28:19 -05:00
processor_display . set_flags ( CAN_FOCUS ) ;
2011-01-05 19:29:40 -05:00
processor_display . set_name ( " ProcessorList " ) ;
2009-11-25 09:37:20 -05:00
processor_display . set_data ( " processorbox " , this ) ;
2013-01-24 20:36:46 -05:00
processor_display . set_size_request ( 48 , - 1 ) ;
2014-01-03 23:54:20 -05:00
processor_display . set_spacing ( 0 ) ;
2007-06-27 16:23:48 -04:00
2009-12-11 18:29:48 -05:00
processor_display . signal_enter_notify_event ( ) . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : enter_notify ) , false ) ;
processor_display . signal_leave_notify_event ( ) . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : leave_notify ) , false ) ;
2009-07-13 19:09:16 -04:00
2009-12-11 18:29:48 -05:00
processor_display . ButtonPress . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : processor_button_press_event ) ) ;
processor_display . ButtonRelease . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : processor_button_release_event ) ) ;
2009-11-25 09:37:20 -05:00
2009-12-11 18:29:48 -05:00
processor_display . Reordered . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : reordered ) ) ;
processor_display . DropFromAnotherBox . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : object_drop ) ) ;
2015-12-21 22:24:20 -05:00
processor_display . DropFromExternal . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : plugin_drop ) ) ;
2011-01-04 18:26:59 -05:00
2011-01-31 20:50:49 -05:00
processor_scroller . show ( ) ;
processor_display . show ( ) ;
2011-01-04 18:26:59 -05:00
if ( parent ) {
parent - > DeliveryChanged . connect (
2012-04-25 08:58:19 -04:00
_mixer_strip_connections , invalidator ( * this ) , boost : : bind ( & ProcessorBox : : mixer_strip_delivery_changed , this , _1 ) , gui_context ( )
2011-01-04 18:26:59 -05:00
) ;
}
2012-01-07 12:10:18 -05:00
2015-01-05 00:32:14 -05:00
ARDOUR_UI_UTILS : : set_tooltip ( processor_display , _ ( " Right-click to add/remove/edit \n plugins,inserts,sends and more " ) ) ;
2007-06-27 16:23:48 -04:00
}
ProcessorBox : : ~ ProcessorBox ( )
{
2011-12-14 21:19:21 -05:00
/* it may appear as if we should delete processor_menu but that is a
* pointer to a widget owned by the UI Manager , and has potentially
* be returned to many other ProcessorBoxes . GTK doesn ' t really make
* clear the ownership of this widget , which is a menu and thus is
* never packed into any container other than an implict GtkWindow .
*
* For now , until or if we ever get clarification over the ownership
* story just let it continue to exist . At worst , its a small memory leak .
*/
2007-06-27 16:23:48 -04:00
}
2008-12-08 11:07:28 -05:00
void
ProcessorBox : : set_route ( boost : : shared_ptr < Route > r )
{
2009-12-04 16:45:07 -05:00
if ( _route = = r ) {
return ;
}
2011-06-01 13:00:29 -04:00
2011-01-04 18:26:59 -05:00
_route_connections . drop_connections ( ) ;
2008-12-08 11:07:28 -05:00
2009-10-08 17:56:16 -04:00
/* new route: any existing block on processor redisplay must be meaningless */
no_processor_redisplay = false ;
2008-12-08 11:07:28 -05:00
_route = r ;
2011-01-04 18:26:59 -05:00
_route - > processors_changed . connect (
2012-04-25 08:58:19 -04:00
_route_connections , invalidator ( * this ) , boost : : bind ( & ProcessorBox : : route_processors_changed , this , _1 ) , gui_context ( )
2011-01-04 18:26:59 -05:00
) ;
2011-06-01 13:00:29 -04:00
2011-01-04 18:26:59 -05:00
_route - > DropReferences . connect (
_route_connections , invalidator ( * this ) , boost : : bind ( & ProcessorBox : : route_going_away , this ) , gui_context ( )
) ;
2011-06-01 13:00:29 -04:00
2011-01-04 18:26:59 -05:00
_route - > PropertyChanged . connect (
2012-04-25 08:58:19 -04:00
_route_connections , invalidator ( * this ) , boost : : bind ( & ProcessorBox : : route_property_changed , this , _1 ) , gui_context ( )
2011-01-04 18:26:59 -05:00
) ;
2008-12-08 11:07:28 -05:00
redisplay_processors ( ) ;
}
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : route_going_away ( )
{
/* don't keep updating display as processors are deleted */
no_processor_redisplay = true ;
2011-05-23 06:03:14 -04:00
_route . reset ( ) ;
2007-06-27 16:23:48 -04:00
}
2015-12-25 11:13:00 -05:00
boost : : shared_ptr < Processor >
ProcessorBox : : find_drop_position ( ProcessorEntry * position )
2015-12-21 22:24:20 -05:00
{
2015-12-25 11:13:00 -05:00
boost : : shared_ptr < Processor > p ;
if ( position ) {
p = position - > processor ( ) ;
if ( ! p ) {
/* dropped on the blank entry (which will be before the
fader ) , so use the first non - blank child as our
` dropped on ' processor */
list < ProcessorEntry * > c = processor_display . children ( ) ;
list < ProcessorEntry * > : : iterator i = c . begin ( ) ;
assert ( i ! = c . end ( ) ) ;
p = ( * i ) - > processor ( ) ;
assert ( p ) ;
2015-12-21 22:24:20 -05:00
}
2015-12-25 11:13:00 -05:00
}
return p ;
}
void
ProcessorBox : : _drop_plugin_preset ( Gtk : : SelectionData const & data , Route : : ProcessorList & pl )
{
const void * d = data . get_data ( ) ;
const Gtkmm2ext : : DnDTreeView < ARDOUR : : PluginPresetPtr > * tv = reinterpret_cast < const Gtkmm2ext : : DnDTreeView < ARDOUR : : PluginPresetPtr > * > ( d ) ;
PluginPresetList nfos ;
TreeView * source ;
tv - > get_object_drag_data ( nfos , & source ) ;
2015-12-21 22:24:20 -05:00
2015-12-25 11:13:00 -05:00
for ( list < PluginPresetPtr > : : const_iterator i = nfos . begin ( ) ; i ! = nfos . end ( ) ; + + i ) {
PluginPresetPtr ppp = ( * i ) ;
PluginInfoPtr pip = ppp - > _pip ;
PluginPtr p = pip - > load ( * _session ) ;
2015-12-21 22:24:20 -05:00
if ( ! p ) {
2015-12-25 11:13:00 -05:00
continue ;
}
if ( ppp - > _preset . valid ) {
p - > load_preset ( ppp - > _preset ) ;
}
boost : : shared_ptr < Processor > processor ( new PluginInsert ( * _session , p ) ) ;
if ( Config - > get_new_plugins_active ( ) ) {
processor - > activate ( ) ;
2015-12-21 22:24:20 -05:00
}
2015-12-25 11:13:00 -05:00
pl . push_back ( processor ) ;
2015-12-21 22:24:20 -05:00
}
2015-12-25 11:13:00 -05:00
}
2015-12-21 22:24:20 -05:00
2015-12-25 11:13:00 -05:00
void
ProcessorBox : : _drop_plugin ( Gtk : : SelectionData const & data , Route : : ProcessorList & pl )
{
2015-12-21 22:24:20 -05:00
const void * d = data . get_data ( ) ;
2015-12-25 11:13:00 -05:00
const Gtkmm2ext : : DnDTreeView < ARDOUR : : PluginInfoPtr > * tv = reinterpret_cast < const Gtkmm2ext : : DnDTreeView < ARDOUR : : PluginInfoPtr > * > ( d ) ;
PluginInfoList nfos ;
2015-12-21 22:24:20 -05:00
TreeView * source ;
tv - > get_object_drag_data ( nfos , & source ) ;
for ( list < PluginInfoPtr > : : const_iterator i = nfos . begin ( ) ; i ! = nfos . end ( ) ; + + i ) {
PluginPtr p = ( * i ) - > load ( * _session ) ;
if ( ! p ) {
continue ;
}
boost : : shared_ptr < Processor > processor ( new PluginInsert ( * _session , p ) ) ;
if ( Config - > get_new_plugins_active ( ) ) {
processor - > activate ( ) ;
}
pl . push_back ( processor ) ;
}
}
2007-06-27 16:23:48 -04:00
void
2015-12-25 11:13:00 -05:00
ProcessorBox : : plugin_drop ( Gtk : : SelectionData const & data , ProcessorEntry * position , Glib : : RefPtr < Gdk : : DragContext > const & context )
2007-06-27 16:23:48 -04:00
{
2015-12-25 11:13:00 -05:00
if ( ! _session ) {
return ;
}
2012-01-29 17:51:36 -05:00
2015-12-25 11:13:00 -05:00
boost : : shared_ptr < Processor > p = find_drop_position ( position ) ;
Route : : ProcessorList pl ;
if ( data . get_target ( ) = = " PluginInfoPtr " ) {
_drop_plugin ( data , pl ) ;
}
2016-05-06 08:55:36 -04:00
else if ( data . get_target ( ) = = " PluginFavoritePtr " ) {
2015-12-25 11:13:00 -05:00
_drop_plugin_preset ( data , pl ) ;
}
else {
return ;
}
Route : : ProcessorStreams err ;
if ( _route - > add_processors ( pl , p , & err ) ) {
string msg = _ (
" Processor Drag/Drop failed. Probably because \n \
the I / O configuration of the plugins could \ n \
not match the configuration of this track . " );
MessageDialog am ( msg ) ;
am . run ( ) ;
2009-11-25 09:37:20 -05:00
}
2015-12-25 11:13:00 -05:00
}
void
ProcessorBox : : object_drop ( DnDVBox < ProcessorEntry > * source , ProcessorEntry * position , Glib : : RefPtr < Gdk : : DragContext > const & context )
{
2016-03-11 16:00:12 -05:00
if ( Gdk : : ACTION_LINK = = context - > get_selected_action ( ) ) {
list < ProcessorEntry * > children = source - > selection ( ) ;
assert ( children . size ( ) = = 1 ) ;
ProcessorEntry * other = * children . begin ( ) ;
assert ( other - > can_copy_state ( position ) ) ;
boost : : shared_ptr < ARDOUR : : Processor > otherproc = other - > processor ( ) ;
boost : : shared_ptr < ARDOUR : : Processor > proc = position - > processor ( ) ;
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( proc ) ;
assert ( otherproc & & proc & & pi ) ;
PBD : : ID id = pi - > id ( ) ;
XMLNode & state = otherproc - > get_state ( ) ;
2016-04-13 12:53:54 -04:00
/* strip side-chain state (processor inside processor must be a side-chain)
* otherwise we ' ll end up with duplicate ports - names .
* ( this needs a better solution which retains connections )
*/
state . remove_nodes ( " Processor " ) ;
2016-03-11 16:00:12 -05:00
proc - > set_state ( state , Stateful : : loading_state_version ) ;
boost : : dynamic_pointer_cast < PluginInsert > ( proc ) - > update_id ( id ) ;
return ;
}
2015-12-25 11:13:00 -05:00
boost : : shared_ptr < Processor > p = find_drop_position ( position ) ;
2009-07-15 16:29:02 -04:00
2009-11-25 09:37:20 -05:00
list < ProcessorEntry * > children = source - > selection ( ) ;
list < boost : : shared_ptr < Processor > > procs ;
for ( list < ProcessorEntry * > : : const_iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
2012-01-08 20:33:24 -05:00
if ( ( * i ) - > processor ( ) ) {
2015-08-15 15:29:19 -04:00
if ( boost : : dynamic_pointer_cast < UnknownProcessor > ( ( * i ) - > processor ( ) ) ) {
continue ;
}
2012-01-08 20:33:24 -05:00
procs . push_back ( ( * i ) - > processor ( ) ) ;
}
2009-07-15 16:29:02 -04:00
}
2009-05-15 22:51:17 -04:00
for ( list < boost : : shared_ptr < Processor > > : : const_iterator i = procs . begin ( ) ; i ! = procs . end ( ) ; + + i ) {
2009-02-14 14:45:30 -05:00
XMLNode & state = ( * i ) - > get_state ( ) ;
XMLNodeList nlist ;
nlist . push_back ( & state ) ;
2009-07-15 16:29:02 -04:00
paste_processor_state ( nlist , p ) ;
2009-02-14 14:45:30 -05:00
delete & state ;
}
2009-10-14 12:10:01 -04:00
2009-11-25 09:37:20 -05:00
/* since the dndvbox doesn't take care of this properly, we have to delete the originals
2009-05-15 22:51:17 -04:00
ourselves .
*/
if ( ( context - > get_suggested_action ( ) = = Gdk : : ACTION_MOVE ) & & source ) {
ProcessorBox * other = reinterpret_cast < ProcessorBox * > ( source - > get_data ( " processorbox " ) ) ;
if ( other ) {
other - > delete_dragged_processors ( procs ) ;
}
}
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : set_width ( Width w )
{
if ( _width = = w ) {
return ;
}
2011-06-01 13:00:29 -04:00
2007-06-27 16:23:48 -04:00
_width = w ;
2009-11-25 09:37:20 -05:00
list < ProcessorEntry * > children = processor_display . children ( ) ;
for ( list < ProcessorEntry * > : : iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
2009-12-04 12:45:11 -05:00
( * i ) - > set_enum_width ( w ) ;
2009-11-25 09:37:20 -05:00
}
2013-01-24 16:58:07 -05:00
queue_resize ( ) ;
2007-06-27 16:23:48 -04:00
}
2009-11-18 23:25:46 -05:00
Gtk : : Menu *
ProcessorBox : : build_possible_aux_menu ( )
{
2009-12-17 13:24:23 -05:00
boost : : shared_ptr < RouteList > rl = _session - > get_routes_with_internal_returns ( ) ;
2009-11-19 16:49:42 -05:00
2012-06-08 10:29:14 -04:00
if ( rl - > empty ( ) ) {
/* No aux sends if there are no busses */
2009-11-18 23:25:46 -05:00
return 0 ;
}
2015-12-21 07:02:19 -05:00
if ( _route - > is_monitor ( ) ) {
return 0 ;
}
2009-11-18 23:25:46 -05:00
using namespace Menu_Helpers ;
Menu * menu = manage ( new Menu ) ;
MenuList & items = menu - > items ( ) ;
for ( RouteList : : iterator r = rl - > begin ( ) ; r ! = rl - > end ( ) ; + + r ) {
2009-11-23 13:08:29 -05:00
if ( ! _route - > internal_send_for ( * r ) & & * r ! = _route ) {
2009-12-11 18:29:48 -05:00
items . push_back ( MenuElem ( ( * r ) - > name ( ) , sigc : : bind ( sigc : : ptr_fun ( ProcessorBox : : rb_choose_aux ) , boost : : weak_ptr < Route > ( * r ) ) ) ) ;
2009-11-18 23:25:46 -05:00
}
}
return menu ;
}
2007-06-27 16:23:48 -04:00
void
2011-10-19 12:53:36 -04:00
ProcessorBox : : show_processor_menu ( int arg )
2007-06-27 16:23:48 -04:00
{
if ( processor_menu = = 0 ) {
processor_menu = build_processor_menu ( ) ;
2011-10-19 12:53:36 -04:00
processor_menu - > signal_unmap ( ) . connect ( sigc : : mem_fun ( * this , & ProcessorBox : : processor_menu_unmapped ) ) ;
2007-06-27 16:23:48 -04:00
}
2011-11-08 09:44:06 -05:00
/* Sort out the plugin submenu */
2011-03-01 18:25:42 -05:00
Gtk : : MenuItem * plugin_menu_item = dynamic_cast < Gtk : : MenuItem * > ( ActionManager : : get_widget ( " /ProcessorMenu/newplugin " ) ) ;
2008-09-10 11:03:30 -04:00
if ( plugin_menu_item ) {
2009-11-15 12:19:38 -05:00
plugin_menu_item - > set_submenu ( * _get_plugin_selector ( ) - > plugin_menu ( ) ) ;
2008-09-10 11:03:30 -04:00
}
2011-11-08 09:44:06 -05:00
/* And the aux submenu */
2011-03-01 18:25:42 -05:00
Gtk : : MenuItem * aux_menu_item = dynamic_cast < Gtk : : MenuItem * > ( ActionManager : : get_widget ( " /ProcessorMenu/newaux " ) ) ;
2009-11-18 23:25:46 -05:00
if ( aux_menu_item ) {
Menu * m = build_possible_aux_menu ( ) ;
2009-11-23 13:08:29 -05:00
if ( m & & ! m - > items ( ) . empty ( ) ) {
2009-11-18 23:25:46 -05:00
aux_menu_item - > set_submenu ( * m ) ;
2009-11-23 13:08:29 -05:00
aux_menu_item - > set_sensitive ( true ) ;
2009-11-18 23:25:46 -05:00
} else {
2009-11-19 16:49:42 -05:00
/* stupid gtkmm: we need to pass a null reference here */
2009-11-20 10:26:34 -05:00
gtk_menu_item_set_submenu ( aux_menu_item - > gobj ( ) , 0 ) ;
2009-11-23 13:08:29 -05:00
aux_menu_item - > set_sensitive ( false ) ;
2009-11-18 23:25:46 -05:00
}
}
2015-12-21 07:02:19 -05:00
ActionManager : : get_action ( X_ ( " ProcessorMenu " ) , " newinsert " ) - > set_sensitive ( ! _route - > is_monitor ( ) ) ;
ActionManager : : get_action ( X_ ( " ProcessorMenu " ) , " newsend " ) - > set_sensitive ( ! _route - > is_monitor ( ) ) ;
2012-01-21 15:32:13 -05:00
ProcessorEntry * single_selection = 0 ;
2012-01-20 13:02:48 -05:00
if ( processor_display . selection ( ) . size ( ) = = 1 ) {
2012-01-21 15:32:13 -05:00
single_selection = processor_display . selection ( ) . front ( ) ;
2012-01-20 13:02:48 -05:00
}
/* And the controls submenu */
Gtk : : MenuItem * controls_menu_item = dynamic_cast < Gtk : : MenuItem * > ( ActionManager : : get_widget ( " /ProcessorMenu/controls " ) ) ;
if ( controls_menu_item ) {
if ( single_selection ) {
2012-01-21 15:32:13 -05:00
Menu * m = single_selection - > build_controls_menu ( ) ;
2012-01-20 13:02:48 -05:00
if ( m & & ! m - > items ( ) . empty ( ) ) {
controls_menu_item - > set_submenu ( * m ) ;
controls_menu_item - > set_sensitive ( true ) ;
} else {
gtk_menu_item_set_submenu ( controls_menu_item - > gobj ( ) , 0 ) ;
controls_menu_item - > set_sensitive ( false ) ;
}
2015-02-10 17:41:46 -05:00
} else {
controls_menu_item - > set_sensitive ( false ) ;
2012-01-20 13:02:48 -05:00
}
}
2016-04-20 15:27:44 -04:00
if ( ! ARDOUR : : Profile - > get_mixbus ( ) ) {
Gtk : : MenuItem * send_menu_item = dynamic_cast < Gtk : : MenuItem * > ( ActionManager : : get_widget ( " /ProcessorMenu/send_options " ) ) ;
if ( send_menu_item ) {
if ( single_selection & & ! _route - > is_monitor ( ) ) {
Menu * m = single_selection - > build_send_options_menu ( ) ;
if ( m & & ! m - > items ( ) . empty ( ) ) {
send_menu_item - > set_submenu ( * m ) ;
send_menu_item - > set_sensitive ( true ) ;
} else {
gtk_menu_item_set_submenu ( send_menu_item - > gobj ( ) , 0 ) ;
send_menu_item - > set_sensitive ( false ) ;
}
2014-01-13 17:21:30 -05:00
} else {
send_menu_item - > set_sensitive ( false ) ;
}
}
}
2011-11-08 09:44:06 -05:00
/* Sensitise actions as approprioate */
2015-08-15 15:29:19 -04:00
const bool sensitive = ! processor_display . selection ( ) . empty ( ) & & ! stub_processor_selected ( ) ;
2007-06-27 16:23:48 -04:00
paste_action - > set_sensitive ( ! _rr_selection . processors . empty ( ) ) ;
2015-08-15 15:29:19 -04:00
cut_action - > set_sensitive ( sensitive & & can_cut ( ) ) ;
copy_action - > set_sensitive ( sensitive ) ;
delete_action - > set_sensitive ( sensitive | | stub_processor_selected ( ) ) ;
2007-06-27 16:23:48 -04:00
2011-11-08 09:44:06 -05:00
edit_action - > set_sensitive ( one_processor_can_be_edited ( ) ) ;
2013-06-06 17:55:08 -04:00
edit_generic_action - > set_sensitive ( one_processor_can_be_edited ( ) ) ;
2011-11-08 09:44:06 -05:00
boost : : shared_ptr < PluginInsert > pi ;
if ( single_selection ) {
2012-01-21 15:32:13 -05:00
pi = boost : : dynamic_pointer_cast < PluginInsert > ( single_selection - > processor ( ) ) ;
2011-11-08 09:44:06 -05:00
}
2016-03-27 15:35:42 -04:00
manage_pins_action - > set_sensitive ( pi ! = 0 ) ;
2012-01-21 17:10:07 -05:00
/* allow editing with an Ardour-generated UI for plugin inserts with editors */
2013-06-06 12:04:23 -04:00
edit_action - > set_sensitive ( pi & & pi - > plugin ( ) - > has_editor ( ) ) ;
2012-01-21 17:10:07 -05:00
2011-11-08 09:44:06 -05:00
/* disallow rename for multiple selections, for plugin inserts and for the fader */
2015-08-15 15:29:19 -04:00
rename_action - > set_sensitive ( single_selection
& & ! pi
& & ! boost : : dynamic_pointer_cast < Amp > ( single_selection - > processor ( ) )
& & ! boost : : dynamic_pointer_cast < UnknownProcessor > ( single_selection - > processor ( ) ) ) ;
2011-11-08 09:44:06 -05:00
2007-06-27 16:23:48 -04:00
processor_menu - > popup ( 1 , arg ) ;
2011-10-19 12:53:36 -04:00
/* Add a placeholder gap to the processor list to indicate where a processor would be
inserted were one chosen from the menu .
*/
int x , y ;
processor_display . get_pointer ( x , y ) ;
_placement = processor_display . add_placeholder ( y ) ;
2012-01-07 12:10:18 -05:00
2012-01-30 13:09:54 -05:00
if ( _visible_prefader_processors = = 0 & & _placement > 0 ) {
- - _placement ;
2012-01-07 12:10:18 -05:00
}
2007-06-27 16:23:48 -04:00
}
2009-07-13 19:09:16 -04:00
bool
2009-07-21 11:55:17 -04:00
ProcessorBox : : enter_notify ( GdkEventCrossing * )
2009-07-13 19:09:16 -04:00
{
2016-03-15 12:40:53 -04:00
processor_display . grab_focus ( ) ;
2009-07-13 19:09:16 -04:00
_current_processor_box = this ;
return false ;
}
bool
2016-03-15 12:40:53 -04:00
ProcessorBox : : leave_notify ( GdkEventCrossing * ev )
2009-07-13 19:09:16 -04:00
{
2016-03-15 12:40:53 -04:00
if ( ev - > detail = = GDK_NOTIFY_INFERIOR ) {
return false ;
}
Widget * top = get_toplevel ( ) ;
if ( top - > is_toplevel ( ) ) {
Window * win = dynamic_cast < Window * > ( top ) ;
gtk_window_set_focus ( win - > gobj ( ) , 0 ) ;
}
2009-07-13 19:09:16 -04:00
return false ;
}
2014-07-24 13:30:11 -04:00
bool
2015-10-04 14:51:05 -04:00
ProcessorBox : : processor_operation ( ProcessorOperation op )
2009-07-13 19:09:16 -04:00
{
ProcSelection targets ;
get_selected_processors ( targets ) ;
2014-07-24 23:49:33 -04:00
/* if (targets.empty()) {
2009-07-13 19:09:16 -04:00
int x , y ;
processor_display . get_pointer ( x , y ) ;
2009-10-14 12:10:01 -04:00
2010-11-25 12:41:04 -05:00
pair < ProcessorEntry * , double > const pointer = processor_display . get_child_at_position ( y ) ;
2009-11-25 09:37:20 -05:00
2012-01-07 12:10:18 -05:00
if ( pointer . first & & pointer . first - > processor ( ) ) {
2009-11-25 09:37:20 -05:00
targets . push_back ( pointer . first - > processor ( ) ) ;
2009-07-13 19:09:16 -04:00
}
}
2014-07-24 13:30:11 -04:00
*/
2009-10-14 12:10:01 -04:00
2016-03-15 12:40:53 -04:00
if ( ( op = = ProcessorsDelete ) & & targets . empty ( ) ) {
2014-07-24 23:49:33 -04:00
return false ; //nothing to delete. return false so the editor-mixer, because the user was probably intending to delete something in the editor
2016-03-15 12:40:53 -04:00
}
2015-10-05 10:17:49 -04:00
2011-11-04 13:53:21 -04:00
switch ( op ) {
case ProcessorsSelectAll :
processor_display . select_all ( ) ;
2009-11-27 21:18:41 -05:00
break ;
2014-07-24 23:49:33 -04:00
case ProcessorsSelectNone :
processor_display . select_none ( ) ;
break ;
2011-11-04 13:53:21 -04:00
case ProcessorsCopy :
copy_processors ( targets ) ;
2009-07-15 16:29:02 -04:00
break ;
2011-11-04 13:53:21 -04:00
case ProcessorsCut :
cut_processors ( targets ) ;
2009-07-15 16:29:02 -04:00
break ;
2011-11-04 13:53:21 -04:00
case ProcessorsPaste :
2015-08-24 19:09:41 -04:00
// some processors are not selectable (e.g fader, meter), target is empty.
if ( targets . empty ( ) & & _placement > = 0 ) {
assert ( _route ) ;
boost : : shared_ptr < Processor > proc = _route - > before_processor_for_index ( _placement ) ;
if ( proc ) {
targets . push_back ( proc ) ;
}
}
2011-11-04 13:53:21 -04:00
if ( targets . empty ( ) ) {
paste_processors ( ) ;
} else {
paste_processors ( targets . front ( ) ) ;
2009-07-15 16:29:02 -04:00
}
break ;
2011-11-04 13:53:21 -04:00
case ProcessorsDelete :
2009-07-15 16:29:02 -04:00
delete_processors ( targets ) ;
2009-07-13 19:09:16 -04:00
break ;
2011-11-04 13:53:21 -04:00
case ProcessorsToggleActive :
2009-07-13 19:09:16 -04:00
for ( ProcSelection : : iterator i = targets . begin ( ) ; i ! = targets . end ( ) ; + + i ) {
if ( ( * i ) - > active ( ) ) {
( * i ) - > deactivate ( ) ;
} else {
( * i ) - > activate ( ) ;
}
}
break ;
2009-10-14 12:10:01 -04:00
2011-11-04 13:53:21 -04:00
case ProcessorsAB :
2009-11-30 08:13:57 -05:00
ab_plugins ( ) ;
break ;
2009-07-13 19:09:16 -04:00
default :
break ;
}
2015-10-05 10:17:49 -04:00
2014-07-24 13:30:11 -04:00
return true ;
2009-07-13 19:09:16 -04:00
}
2015-10-04 14:51:05 -04:00
ProcessorWindowProxy *
2013-05-04 22:02:05 -04:00
ProcessorBox : : find_window_proxy ( boost : : shared_ptr < Processor > processor ) const
{
2014-11-28 19:35:49 -05:00
return processor - > window_proxy ( ) ;
2013-05-04 22:02:05 -04:00
}
2007-06-27 16:23:48 -04:00
bool
2009-11-25 09:37:20 -05:00
ProcessorBox : : processor_button_press_event ( GdkEventButton * ev , ProcessorEntry * child )
2007-06-27 16:23:48 -04:00
{
boost : : shared_ptr < Processor > processor ;
2009-11-25 09:37:20 -05:00
if ( child ) {
processor = child - > processor ( ) ;
2007-06-27 16:23:48 -04:00
}
2011-06-01 13:00:29 -04:00
2009-11-25 09:37:20 -05:00
int ret = false ;
bool selected = processor_display . selected ( child ) ;
2007-06-27 16:23:48 -04:00
if ( processor & & ( Keyboard : : is_edit_event ( ev ) | | ( ev - > button = = 1 & & ev - > type = = GDK_2BUTTON_PRESS ) ) ) {
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-12-17 13:24:23 -05:00
if ( _session - > engine ( ) . connected ( ) ) {
2007-06-27 16:23:48 -04:00
/* XXX giving an error message here is hard, because we may be in the midst of a button press */
2013-05-04 22:02:05 -04:00
2015-04-13 22:25:55 -04:00
if ( ! one_processor_can_be_edited ( ) ) {
return true ;
}
2013-06-06 18:40:47 -04:00
2013-06-06 17:55:08 -04:00
if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : SecondaryModifier ) ) {
2013-05-04 22:02:05 -04:00
generic_edit_processor ( processor ) ;
2013-06-06 17:55:08 -04:00
} else {
edit_processor ( processor ) ;
2012-01-22 05:18:37 -05:00
}
2007-06-27 16:23:48 -04:00
}
2013-05-04 22:02:05 -04:00
2007-06-27 16:23:48 -04:00
ret = true ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2014-08-28 15:25:19 -04:00
} else if ( Keyboard : : is_context_menu_event ( ev ) ) {
show_processor_menu ( ev - > time ) ;
2015-10-05 10:17:49 -04:00
2014-08-28 15:25:19 -04:00
ret = true ;
2007-06-27 16:23:48 -04:00
} else if ( processor & & ev - > button = = 1 & & selected ) {
2009-07-15 16:29:02 -04:00
// this is purely informational but necessary for route params UI
2008-09-10 11:03:30 -04:00
ProcessorSelected ( processor ) ; // emit
2008-12-12 09:43:24 -05:00
} else if ( ! processor & & ev - > button = = 1 & & ev - > type = = GDK_2BUTTON_PRESS ) {
choose_plugin ( ) ;
2009-10-22 21:00:13 -04:00
_get_plugin_selector ( ) - > show_manager ( ) ;
2007-06-27 16:23:48 -04:00
}
2008-12-12 09:43:24 -05:00
2007-06-27 16:23:48 -04:00
return ret ;
}
bool
2009-11-25 09:37:20 -05:00
ProcessorBox : : processor_button_release_event ( GdkEventButton * ev , ProcessorEntry * child )
2007-06-27 16:23:48 -04:00
{
boost : : shared_ptr < Processor > processor ;
2009-11-25 09:37:20 -05:00
if ( child ) {
processor = child - > processor ( ) ;
2007-06-27 16:23:48 -04:00
}
2011-06-01 13:00:29 -04:00
2007-06-27 16:23:48 -04:00
if ( processor & & Keyboard : : is_delete_event ( ev ) ) {
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-12-11 18:29:48 -05:00
Glib : : signal_idle ( ) . connect ( sigc : : bind (
sigc : : mem_fun ( * this , & ProcessorBox : : idle_delete_processor ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
boost : : weak_ptr < Processor > ( processor ) ) ) ;
2009-04-15 14:04:23 -04:00
} else if ( processor & & Keyboard : : is_button2_event ( ev )
2015-10-27 13:43:31 -04:00
# ifndef __APPLE__
2009-04-15 14:04:23 -04:00
& & ( Keyboard : : no_modifier_keys_pressed ( ev ) & & ( ( ev - > state & Gdk : : BUTTON2_MASK ) = = Gdk : : BUTTON2_MASK ) )
# endif
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
) {
2009-04-15 14:04:23 -04:00
/* button2-click with no/appropriate modifiers */
2008-09-10 11:03:30 -04:00
2009-01-30 02:40:13 -05:00
if ( processor - > active ( ) ) {
processor - > deactivate ( ) ;
} else {
processor - > activate ( ) ;
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
}
2007-06-27 16:23:48 -04:00
2009-11-25 09:37:20 -05:00
return false ;
2007-06-27 16:23:48 -04:00
}
Menu *
ProcessorBox : : build_processor_menu ( )
{
2011-03-01 18:25:42 -05:00
processor_menu = dynamic_cast < Gtk : : Menu * > ( ActionManager : : get_widget ( " /ProcessorMenu " ) ) ;
2007-06-27 16:23:48 -04:00
processor_menu - > set_name ( " ArdourContextMenu " ) ;
return processor_menu ;
}
void
ProcessorBox : : select_all_processors ( )
{
2009-11-25 09:37:20 -05:00
processor_display . select_all ( ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : deselect_all_processors ( )
{
2009-11-25 09:37:20 -05:00
processor_display . select_none ( ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : choose_plugin ( )
{
2009-10-22 21:00:13 -04:00
_get_plugin_selector ( ) - > set_interested_object ( * this ) ;
2007-06-27 16:23:48 -04:00
}
2010-04-27 15:58:31 -04:00
/** @return true if an error occurred, otherwise false */
bool
2008-09-10 11:03:30 -04:00
ProcessorBox : : use_plugins ( const SelectedPlugins & plugins )
2007-06-27 16:23:48 -04:00
{
2008-09-10 11:03:30 -04:00
for ( SelectedPlugins : : const_iterator p = plugins . begin ( ) ; p ! = plugins . end ( ) ; + + p ) {
2007-06-27 16:23:48 -04:00
2009-12-17 13:24:23 -05:00
boost : : shared_ptr < Processor > processor ( new PluginInsert ( * _session , * p ) ) ;
2007-06-27 16:23:48 -04:00
2008-09-10 11:03:30 -04:00
Route : : ProcessorStreams err_streams ;
2008-12-12 09:43:24 -05:00
2011-10-19 12:53:36 -04:00
if ( _route - > add_processor_by_index ( processor , _placement , & err_streams , Config - > get_new_plugins_active ( ) ) ) {
2009-06-09 16:21:19 -04:00
weird_plugin_dialog ( * * p , err_streams ) ;
2010-04-27 15:58:31 -04:00
return true ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
// XXX SHAREDPTR delete plugin here .. do we even need to care?
2016-03-15 10:15:23 -04:00
} else if ( plugins . size ( ) = = 1 & & UIConfiguration : : instance ( ) . get_open_gui_after_adding_plugin ( ) ) {
if ( boost : : dynamic_pointer_cast < PluginInsert > ( processor ) - > plugin ( ) - > has_inline_display ( ) & & UIConfiguration : : instance ( ) . get_prefer_inline_over_gui ( ) ) {
2016-03-14 19:27:03 -04:00
;
} else if ( _session - > engine ( ) . connected ( ) & & processor_can_be_edited ( processor ) ) {
2015-11-20 05:14:36 -05:00
if ( ( * p ) - > has_editor ( ) ) {
edit_processor ( processor ) ;
} else {
generic_edit_processor ( processor ) ;
}
2008-09-10 11:03:30 -04:00
}
2007-06-27 16:23:48 -04:00
}
}
2010-04-27 15:58:31 -04:00
return false ;
2007-06-27 16:23:48 -04:00
}
void
2009-06-09 16:21:19 -04:00
ProcessorBox : : weird_plugin_dialog ( Plugin & p , Route : : ProcessorStreams streams )
2007-06-27 16:23:48 -04:00
{
2010-04-27 15:58:31 -04:00
ArdourDialog dialog ( _ ( " Plugin Incompatibility " ) ) ;
2007-06-27 16:23:48 -04:00
Label label ;
2011-05-26 19:47:40 -04:00
string text = string_compose ( _ ( " You attempted to add the plugin \" %1 \" in slot %2. \n " ) ,
2009-05-04 11:50:51 -04:00
p . name ( ) , streams . index ) ;
bool has_midi = streams . count . n_midi ( ) > 0 | | p . get_info ( ) - > n_inputs . n_midi ( ) > 0 ;
bool has_audio = streams . count . n_audio ( ) > 0 | | p . get_info ( ) - > n_inputs . n_audio ( ) > 0 ;
text + = _ ( " \n This plugin has: \n " ) ;
if ( has_midi ) {
2010-12-14 08:05:35 -05:00
uint32_t const n = p . get_info ( ) - > n_inputs . n_midi ( ) ;
2011-02-09 21:44:44 -05:00
text + = string_compose ( ngettext ( " \t %1 MIDI input \n " , " \t %1 MIDI inputs \n " , n ) , n ) ;
2009-05-04 11:50:51 -04:00
}
if ( has_audio ) {
2010-12-14 08:05:35 -05:00
uint32_t const n = p . get_info ( ) - > n_inputs . n_audio ( ) ;
2011-02-09 21:44:44 -05:00
text + = string_compose ( ngettext ( " \t %1 audio input \n " , " \t %1 audio inputs \n " , n ) , n ) ;
2007-06-27 16:23:48 -04:00
}
2011-02-09 21:44:44 -05:00
text + = _ ( " \n but at the insertion point, there are: \n " ) ;
2009-05-04 11:50:51 -04:00
if ( has_midi ) {
2010-12-14 08:05:35 -05:00
uint32_t const n = streams . count . n_midi ( ) ;
text + = string_compose ( ngettext ( " \t %1 MIDI channel \n " , " \t %1 MIDI channels \n " , n ) , n ) ;
2009-05-04 11:50:51 -04:00
}
if ( has_audio ) {
2010-12-14 08:05:35 -05:00
uint32_t const n = streams . count . n_audio ( ) ;
text + = string_compose ( ngettext ( " \t %1 audio channel \n " , " \t %1 audio channels \n " , n ) , n ) ;
2009-05-04 11:50:51 -04:00
}
2010-03-14 22:31:27 -04:00
text + = string_compose ( _ ( " \n %1 is unable to insert this plugin here. \n " ) , PROGRAM_NAME ) ;
2009-05-04 11:50:51 -04:00
label . set_text ( text ) ;
2007-06-27 16:23:48 -04:00
dialog . get_vbox ( ) - > pack_start ( label ) ;
dialog . add_button ( Stock : : OK , RESPONSE_ACCEPT ) ;
dialog . set_name ( X_ ( " PluginIODialog " ) ) ;
dialog . set_modal ( true ) ;
dialog . show_all ( ) ;
dialog . run ( ) ;
}
void
2008-09-10 11:03:30 -04:00
ProcessorBox : : choose_insert ( )
2007-06-27 16:23:48 -04:00
{
2011-01-26 20:31:03 -05:00
boost : : shared_ptr < Processor > processor ( new PortInsert ( * _session , _route - > pannable ( ) , _route - > mute_master ( ) ) ) ;
2011-10-19 12:53:36 -04:00
_route - > add_processor_by_index ( processor , _placement ) ;
2007-06-27 16:23:48 -04:00
}
2010-11-25 18:46:24 -05:00
/* Caller must not hold process lock */
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : choose_send ( )
{
2016-04-17 18:52:24 -04:00
boost : : shared_ptr < Send > send ( new Send ( * _session , _route - > pannable ( ) , _route - > mute_master ( ) ) ) ;
2007-10-11 18:07:47 -04:00
/* make an educated guess at the initial number of outputs for the send */
2009-12-17 13:24:23 -05:00
ChanCount outs = ( _session - > master_out ( ) )
? _session - > master_out ( ) - > n_outputs ( )
2009-05-07 13:31:18 -04:00
: _route - > n_outputs ( ) ;
2007-06-27 16:23:48 -04:00
2008-09-10 11:03:30 -04:00
/* XXX need processor lock on route */
try {
2012-07-25 13:48:55 -04:00
Glib : : Threads : : Mutex : : Lock lm ( AudioEngine : : instance ( ) - > process_lock ( ) ) ;
2009-06-09 16:21:19 -04:00
send - > output ( ) - > ensure_io ( outs , false , this ) ;
2008-09-10 11:03:30 -04:00
} catch ( AudioEngine : : PortRegistrationFailure & err ) {
error < < string_compose ( _ ( " Cannot set up new send: %1 " ) , err . what ( ) ) < < endmsg ;
return ;
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-10-14 12:10:01 -04:00
/* let the user adjust the IO setup before creation.
2009-09-12 22:03:04 -04:00
Note : this dialog is NOT modal - we just leave it to run and it will
return when its Finished signal is emitted - typically when the window
is closed .
*/
2009-12-17 13:24:23 -05:00
IOSelectorWindow * ios = new IOSelectorWindow ( _session , send - > output ( ) , true ) ;
2011-01-10 21:47:53 -05:00
ios - > show ( ) ;
2007-10-11 18:07:47 -04:00
2009-05-07 13:31:18 -04:00
/* keep a reference to the send so it doesn't get deleted while
2009-10-14 12:10:01 -04:00
the IOSelectorWindow is doing its stuff
2009-09-12 22:03:04 -04:00
*/
2009-05-07 13:31:18 -04:00
_processor_being_created = send ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-12-11 18:29:48 -05:00
ios - > selector ( ) . Finished . connect ( sigc : : bind (
sigc : : mem_fun ( * this , & ProcessorBox : : send_io_finished ) ,
2009-05-07 13:31:18 -04:00
boost : : weak_ptr < Processor > ( send ) , ios ) ) ;
2009-09-12 22:03:04 -04:00
2007-06-27 16:23:48 -04:00
}
2008-09-10 11:03:30 -04:00
void
ProcessorBox : : send_io_finished ( IOSelector : : Result r , boost : : weak_ptr < Processor > weak_processor , IOSelectorWindow * ios )
2007-06-27 16:23:48 -04:00
{
2008-09-10 11:03:30 -04:00
boost : : shared_ptr < Processor > processor ( weak_processor . lock ( ) ) ;
2009-05-07 13:31:18 -04:00
/* drop our temporary reference to the new send */
_processor_being_created . reset ( ) ;
if ( ! processor ) {
return ;
}
switch ( r ) {
case IOSelector : : Cancelled :
// processor will go away when all shared_ptrs to it vanish
break ;
case IOSelector : : Accepted :
2011-10-19 12:53:36 -04:00
_route - > add_processor_by_index ( processor , _placement ) ;
2009-05-07 13:31:18 -04:00
break ;
}
delete_when_idle ( ios ) ;
}
void
ProcessorBox : : return_io_finished ( IOSelector : : Result r , boost : : weak_ptr < Processor > weak_processor , IOSelectorWindow * ios )
{
boost : : shared_ptr < Processor > processor ( weak_processor . lock ( ) ) ;
/* drop our temporary reference to the new return */
_processor_being_created . reset ( ) ;
2009-01-21 18:29:15 -05:00
2008-09-10 11:03:30 -04:00
if ( ! processor ) {
return ;
}
switch ( r ) {
case IOSelector : : Cancelled :
// processor will go away when all shared_ptrs to it vanish
break ;
case IOSelector : : Accepted :
2011-10-19 12:53:36 -04:00
_route - > add_processor_by_index ( processor , _placement ) ;
2008-09-10 11:03:30 -04:00
break ;
}
delete_when_idle ( ios ) ;
2007-06-27 16:23:48 -04:00
}
2009-11-18 23:25:46 -05:00
void
ProcessorBox : : choose_aux ( boost : : weak_ptr < Route > wr )
{
if ( ! _route ) {
return ;
}
boost : : shared_ptr < Route > target = wr . lock ( ) ;
if ( ! target ) {
return ;
}
2012-01-30 13:09:54 -05:00
_session - > add_internal_send ( target , _placement , _route ) ;
2009-11-18 23:25:46 -05:00
}
2009-11-30 18:16:28 -05:00
void
ProcessorBox : : route_processors_changed ( RouteProcessorChange c )
{
if ( c . type = = RouteProcessorChange : : MeterPointChange & & c . meter_visibly_changed = = false ) {
/* the meter has moved, but it was and still is invisible to the user, so nothing to do */
return ;
}
redisplay_processors ( ) ;
}
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : redisplay_processors ( )
{
2012-01-07 12:10:18 -05:00
ENSURE_GUI_THREAD ( * this , & ProcessorBox : : redisplay_processors ) ;
bool fader_seen ;
2007-06-27 16:23:48 -04:00
if ( no_processor_redisplay ) {
return ;
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-11-25 09:37:20 -05:00
processor_display . clear ( ) ;
2007-06-27 16:23:48 -04:00
2012-01-07 12:10:18 -05:00
_visible_prefader_processors = 0 ;
fader_seen = false ;
2015-10-04 14:51:05 -04:00
_route - > foreach_processor ( sigc : : bind ( sigc : : mem_fun ( * this , & ProcessorBox : : help_count_visible_prefader_processors ) ,
2014-01-05 10:02:40 -05:00
& _visible_prefader_processors , & fader_seen ) ) ;
2012-01-07 12:10:18 -05:00
2009-12-11 18:29:48 -05:00
_route - > foreach_processor ( sigc : : mem_fun ( * this , & ProcessorBox : : add_processor_to_display ) ) ;
2010-08-17 22:20:15 -04:00
_route - > foreach_processor ( sigc : : mem_fun ( * this , & ProcessorBox : : maybe_add_processor_to_ui_list ) ) ;
2016-03-27 15:35:42 -04:00
_route - > foreach_processor ( sigc : : mem_fun ( * this , & ProcessorBox : : maybe_add_processor_pin_mgr ) ) ;
2016-03-31 14:44:39 -04:00
2011-01-14 10:48:45 -05:00
setup_entry_positions ( ) ;
2010-08-17 22:20:15 -04:00
}
/** Add a ProcessorWindowProxy for a processor to our list, if that processor does
* not already have one .
*/
void
ProcessorBox : : maybe_add_processor_to_ui_list ( boost : : weak_ptr < Processor > w )
{
boost : : shared_ptr < Processor > p = w . lock ( ) ;
if ( ! p ) {
return ;
}
2014-11-28 19:35:49 -05:00
if ( p - > window_proxy ( ) ) {
return ;
2010-08-17 22:20:15 -04:00
}
/* not on the list; add it */
string loc ;
2014-11-28 19:35:49 -05:00
#if 0 // is this still needed? Why?
2010-08-17 22:20:15 -04:00
if ( _parent_strip ) {
if ( _parent_strip - > mixer_owned ( ) ) {
loc = X_ ( " M " ) ;
} else {
loc = X_ ( " R " ) ;
}
} else {
loc = X_ ( " P " ) ;
}
2014-11-28 19:35:49 -05:00
# else
loc = X_ ( " P " ) ;
# endif
2011-06-01 13:00:29 -04:00
2010-08-17 22:20:15 -04:00
ProcessorWindowProxy * wp = new ProcessorWindowProxy (
string_compose ( " %1-%2-%3 " , loc , _route - > id ( ) , p - > id ( ) ) ,
this ,
w ) ;
2011-06-01 13:00:29 -04:00
2013-05-04 22:02:05 -04:00
const XMLNode * ui_xml = _session - > extra_xml ( X_ ( " UI " ) ) ;
if ( ui_xml ) {
2015-07-07 22:12:21 -04:00
wp - > set_state ( * ui_xml , 0 ) ;
2013-05-04 22:02:05 -04:00
}
2015-10-05 10:17:49 -04:00
2011-01-31 21:41:31 -05:00
void * existing_ui = p - > get_ui ( ) ;
if ( existing_ui ) {
2013-05-04 22:02:05 -04:00
wp - > use_window ( * ( reinterpret_cast < Gtk : : Window * > ( existing_ui ) ) ) ;
2011-01-31 21:41:31 -05:00
}
2014-11-28 19:35:49 -05:00
p - > set_window_proxy ( wp ) ;
2013-05-07 22:09:16 -04:00
WM : : Manager : : instance ( ) . register_window ( wp ) ;
2007-06-27 16:23:48 -04:00
}
2016-03-27 15:35:42 -04:00
void
ProcessorBox : : maybe_add_processor_pin_mgr ( boost : : weak_ptr < Processor > w )
{
boost : : shared_ptr < Processor > p = w . lock ( ) ;
if ( ! p | | p - > pinmgr_proxy ( ) ) {
return ;
}
PluginPinWindowProxy * wp = new PluginPinWindowProxy (
string_compose ( " PM-%2-%3 " , _route - > id ( ) , p - > id ( ) ) , w ) ;
2016-04-02 23:21:40 -04:00
wp - > set_session ( _session ) ;
2016-03-27 15:35:42 -04:00
const XMLNode * ui_xml = _session - > extra_xml ( X_ ( " UI " ) ) ;
if ( ui_xml ) {
wp - > set_state ( * ui_xml , 0 ) ;
}
p - > set_pingmgr_proxy ( wp ) ;
WM : : Manager : : instance ( ) . register_window ( wp ) ;
}
2012-01-07 12:10:18 -05:00
void
2014-01-05 10:02:40 -05:00
ProcessorBox : : help_count_visible_prefader_processors ( boost : : weak_ptr < Processor > p , uint32_t * cnt , bool * amp_seen )
2012-01-07 12:10:18 -05:00
{
boost : : shared_ptr < Processor > processor ( p . lock ( ) ) ;
2015-10-04 13:39:53 -04:00
if ( processor & & ( processor - > display_to_user ( )
# ifndef NDEBUG
| | show_all_processors
# endif
)
) {
2012-01-07 12:10:18 -05:00
2016-03-14 11:44:51 -04:00
if ( boost : : dynamic_pointer_cast < Amp > ( processor ) & &
2016-01-12 14:09:24 -05:00
boost : : dynamic_pointer_cast < Amp > ( processor ) - > gain_control ( ) - > parameter ( ) . type ( ) = = GainAutomation ) {
2012-01-07 12:10:18 -05:00
* amp_seen = true ;
} else {
if ( ! * amp_seen ) {
( * cnt ) + + ;
}
}
}
}
2007-06-27 16:23:48 -04:00
void
2008-12-16 18:21:01 -05:00
ProcessorBox : : add_processor_to_display ( boost : : weak_ptr < Processor > p )
2007-06-27 16:23:48 -04:00
{
2008-12-16 18:21:01 -05:00
boost : : shared_ptr < Processor > processor ( p . lock ( ) ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2015-10-04 13:39:53 -04:00
if ( ! processor | | ( ! processor - > display_to_user ( )
# ifndef NDEBUG
& & ! show_all_processors
# endif
)
) {
2007-06-27 16:23:48 -04:00
return ;
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2011-01-31 20:50:49 -05:00
boost : : shared_ptr < PluginInsert > plugin_insert = boost : : dynamic_pointer_cast < PluginInsert > ( processor ) ;
2015-10-05 10:17:49 -04:00
2009-12-04 12:45:11 -05:00
ProcessorEntry * e = 0 ;
2012-01-21 11:38:45 -05:00
if ( plugin_insert ) {
2012-01-21 15:32:13 -05:00
e = new PluginInsertProcessorEntry ( this , plugin_insert , _width ) ;
2007-06-27 16:23:48 -04:00
} else {
2012-01-21 15:32:13 -05:00
e = new ProcessorEntry ( this , processor , _width ) ;
2007-06-27 16:23:48 -04:00
}
2011-06-01 13:00:29 -04:00
2014-07-28 11:08:17 -04:00
boost : : shared_ptr < Send > send = boost : : dynamic_pointer_cast < Send > ( processor ) ;
boost : : shared_ptr < PortInsert > ext = boost : : dynamic_pointer_cast < PortInsert > ( processor ) ;
2015-08-15 15:29:19 -04:00
boost : : shared_ptr < UnknownProcessor > stub = boost : : dynamic_pointer_cast < UnknownProcessor > ( processor ) ;
2015-10-05 10:17:49 -04:00
2014-07-28 11:08:17 -04:00
//faders and meters are not deletable, copy/paste-able, so they shouldn't be selectable
2015-08-15 15:29:19 -04:00
if ( ! send & & ! plugin_insert & & ! ext & & ! stub )
2014-07-28 11:08:17 -04:00
e - > set_selectable ( false ) ;
2015-03-25 06:10:58 -04:00
bool mark_send_visible = false ;
if ( send & & _parent_strip ) {
/* show controls of new sends by default */
GUIObjectState & st = _parent_strip - > gui_object_state ( ) ;
XMLNode * strip = st . get_or_add_node ( _parent_strip - > state_id ( ) ) ;
assert ( strip ) ;
/* check if state exists, if not it must be a new send */
if ( ! st . get_node ( strip , e - > state_id ( ) ) ) {
mark_send_visible = true ;
}
}
2012-01-20 13:02:48 -05:00
/* Set up this entry's state from the GUIObjectState */
XMLNode * proc = entry_gui_object_state ( e ) ;
if ( proc ) {
e - > set_control_state ( proc ) ;
}
2015-03-25 06:10:58 -04:00
if ( mark_send_visible ) {
2012-01-21 11:38:45 -05:00
e - > show_all_controls ( ) ;
}
2015-12-30 06:15:25 -05:00
if ( plugin_insert
# ifdef MIXBUS
& & ! plugin_insert - > plugin ( 0 ) - > is_channelstrip ( )
# endif
)
{
2016-01-01 07:24:23 -05:00
processor_display . add_child ( e , drag_targets ( ) ) ;
2015-12-30 06:15:25 -05:00
} else {
2016-01-01 07:24:23 -05:00
processor_display . add_child ( e , drag_targets_noplugin ( ) ) ;
2015-12-30 06:15:25 -05:00
}
2007-06-27 16:23:48 -04:00
}
void
2009-11-25 09:37:20 -05:00
ProcessorBox : : reordered ( )
2007-06-27 16:23:48 -04:00
{
2009-11-25 09:37:20 -05:00
compute_processor_sort_keys ( ) ;
2011-01-14 10:48:45 -05:00
setup_entry_positions ( ) ;
2011-01-05 19:29:40 -05:00
}
2016-03-31 14:44:39 -04:00
void
ProcessorBox : : setup_routing_feeds ( )
{
list < ProcessorEntry * > children = processor_display . children ( ) ;
2016-04-16 15:28:37 -04:00
/* first set the i/o maps for every processor */
list < ProcessorEntry * > : : iterator prev = children . begin ( ) ;
2016-03-31 14:44:39 -04:00
for ( list < ProcessorEntry * > : : iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
boost : : shared_ptr < ARDOUR : : Processor > p = ( * i ) - > processor ( ) ;
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( p ) ;
list < ProcessorEntry * > : : iterator next = i ;
next + + ;
if ( pi ) {
ChanCount sinks = pi - > natural_input_streams ( ) ;
ChanCount sources = pi - > natural_output_streams ( ) ;
uint32_t count = pi - > get_count ( ) ;
ChanCount in , out ;
pi - > configured_io ( in , out ) ;
2016-04-04 09:14:41 -04:00
ChanCount midi_thru ;
2016-03-31 14:44:39 -04:00
ChanCount midi_bypass ;
2016-04-04 08:58:46 -04:00
ChanMapping input_map ( pi - > input_map ( ) ) ;
2016-04-04 09:14:41 -04:00
if ( pi - > has_midi_thru ( ) ) {
midi_thru . set ( DataType : : MIDI , 1 ) ;
2016-04-04 08:58:46 -04:00
input_map . set ( DataType : : MIDI , 0 , 0 ) ;
}
2016-03-31 14:44:39 -04:00
if ( pi - > has_midi_bypass ( ) ) {
midi_bypass . set ( DataType : : MIDI , 1 ) ;
}
2016-04-04 09:14:41 -04:00
( * i ) - > input_icon . set_ports ( sinks * count + midi_thru ) ;
2016-03-31 14:44:39 -04:00
( * i ) - > output_icon . set_ports ( sources * count + midi_bypass ) ;
( * i ) - > routing_icon . set (
in , out ,
2016-04-04 09:14:41 -04:00
sinks * count + midi_thru ,
2016-03-31 14:44:39 -04:00
sources * count + midi_bypass ,
2016-04-04 08:58:46 -04:00
input_map ,
2016-04-07 12:36:04 -04:00
pi - > output_map ( ) ,
pi - > thru_map ( ) ) ;
2016-03-31 14:44:39 -04:00
if ( next ! = children . end ( ) ) {
2016-04-16 15:28:37 -04:00
( * next ) - > routing_icon . set_fed_by ( out , sources * count + midi_bypass ,
pi - > output_map ( ) , pi - > thru_map ( ) ) ;
}
if ( prev ! = i ) {
( * prev ) - > routing_icon . set_feeding ( in , sinks * count + midi_thru ,
pi - > input_map ( ) , pi - > thru_map ( ) ) ;
2016-03-31 14:44:39 -04:00
}
} else {
( * i ) - > input_icon . set_ports ( p - > input_streams ( ) ) ;
( * i ) - > output_icon . set_ports ( p - > output_streams ( ) ) ;
ChanMapping inmap ( p - > input_streams ( ) ) ;
ChanMapping outmap ( p - > input_streams ( ) ) ;
2016-04-07 12:36:04 -04:00
ChanMapping thrumap ;
2016-03-31 14:44:39 -04:00
( * i ) - > routing_icon . set (
p - > input_streams ( ) ,
p - > output_streams ( ) ,
p - > input_streams ( ) ,
p - > output_streams ( ) ,
2016-04-07 12:36:04 -04:00
inmap , outmap , thrumap ) ;
2016-03-31 14:44:39 -04:00
if ( next ! = children . end ( ) ) {
2016-04-16 15:28:37 -04:00
( * next ) - > routing_icon . set_fed_by (
p - > output_streams ( ) ,
p - > output_streams ( ) ,
outmap , thrumap ) ;
}
if ( prev ! = i ) {
( * prev ) - > routing_icon . set_feeding (
p - > input_streams ( ) ,
p - > output_streams ( ) ,
inmap , thrumap ) ;
2016-03-31 14:44:39 -04:00
}
}
if ( i = = children . begin ( ) ) {
2016-04-16 15:28:37 -04:00
( * i ) - > routing_icon . unset_fed_by ( ) ;
2016-03-31 14:44:39 -04:00
}
2016-04-16 15:28:37 -04:00
prev = i ;
2016-04-17 15:49:44 -04:00
( * i ) - > input_icon . hide ( ) ;
2016-03-31 14:44:39 -04:00
}
2016-04-16 15:28:37 -04:00
/* now set which icons need to be displayed */
2016-03-31 14:44:39 -04:00
for ( list < ProcessorEntry * > : : iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
2016-04-16 15:28:37 -04:00
( * i ) - > output_routing_icon . copy_state ( ( * i ) - > routing_icon ) ;
if ( ( * i ) - > routing_icon . in_identity ( ) ) {
2016-03-31 14:44:39 -04:00
( * i ) - > routing_icon . hide ( ) ;
if ( i = = children . begin ( ) ) {
( * i ) - > input_icon . show ( ) ;
}
} else {
( * i ) - > routing_icon . show ( ) ;
2016-04-01 16:57:33 -04:00
( * i ) - > routing_icon . queue_draw ( ) ;
2016-03-31 14:44:39 -04:00
( * i ) - > input_icon . show ( ) ;
}
2016-04-03 19:27:33 -04:00
list < ProcessorEntry * > : : iterator next = i ;
if ( + + next = = children . end ( ) ) {
2016-04-16 15:28:37 -04:00
// last processor in the chain
( * i ) - > output_routing_icon . set_terminal ( true ) ;
( * i ) - > output_routing_icon . unset_feeding ( ) ;
2016-04-03 19:27:33 -04:00
if ( ( * i ) - > routing_icon . out_identity ( ) ) {
( * i ) - > output_routing_icon . hide ( ) ;
} else {
( * i ) - > output_routing_icon . show ( ) ;
2016-04-16 15:28:37 -04:00
( * i ) - > output_routing_icon . queue_draw ( ) ;
2016-04-03 19:27:33 -04:00
}
} else {
2016-04-16 15:28:37 -04:00
( * i ) - > output_routing_icon . set_terminal ( false ) ;
2016-05-24 12:18:26 -04:00
if ( ! ( * i ) - > routing_icon . out_identity ( )
& & ! ( * next ) - > routing_icon . in_identity ( )
& & ( * next ) - > routing_icon . can_coalesce ( ) ) {
2016-04-16 15:28:37 -04:00
( * i ) - > output_routing_icon . hide ( ) ;
} else if ( ! ( * i ) - > routing_icon . out_identity ( ) ) {
( * i ) - > output_routing_icon . show ( ) ;
( * i ) - > output_routing_icon . queue_draw ( ) ;
2016-04-17 15:49:44 -04:00
( * next ) - > input_icon . show ( ) ;
2016-04-16 15:28:37 -04:00
} else {
( * i ) - > output_routing_icon . hide ( ) ;
}
2016-04-03 19:27:33 -04:00
}
2016-03-31 14:44:39 -04:00
}
}
2011-01-05 19:29:40 -05:00
void
2011-01-14 10:48:45 -05:00
ProcessorBox : : setup_entry_positions ( )
2011-01-05 19:29:40 -05:00
{
list < ProcessorEntry * > children = processor_display . children ( ) ;
bool pre_fader = true ;
2011-06-01 13:00:29 -04:00
2014-01-05 09:50:13 -05:00
uint32_t num = 0 ;
2011-01-05 19:29:40 -05:00
for ( list < ProcessorEntry * > : : iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
2016-03-14 11:44:51 -04:00
if ( boost : : dynamic_pointer_cast < Amp > ( ( * i ) - > processor ( ) ) & &
2016-01-12 14:09:24 -05:00
boost : : dynamic_pointer_cast < Amp > ( ( * i ) - > processor ( ) ) - > gain_control ( ) - > parameter ( ) . type ( ) = = GainAutomation ) {
2011-01-05 19:29:40 -05:00
pre_fader = false ;
2014-01-05 09:50:13 -05:00
( * i ) - > set_position ( ProcessorEntry : : Fader , num + + ) ;
2011-01-05 19:29:40 -05:00
} else {
if ( pre_fader ) {
2014-01-05 09:50:13 -05:00
( * i ) - > set_position ( ProcessorEntry : : PreFader , num + + ) ;
2011-01-05 19:29:40 -05:00
} else {
2014-01-05 09:50:13 -05:00
( * i ) - > set_position ( ProcessorEntry : : PostFader , num + + ) ;
2011-01-05 19:29:40 -05:00
}
}
}
2016-03-31 14:44:39 -04:00
setup_routing_feeds ( ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : compute_processor_sort_keys ( )
{
2009-11-25 09:37:20 -05:00
list < ProcessorEntry * > children = processor_display . children ( ) ;
2009-05-15 22:51:17 -04:00
Route : : ProcessorList our_processors ;
2009-05-13 17:34:09 -04:00
2012-01-08 20:33:24 -05:00
for ( list < ProcessorEntry * > : : iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
if ( ( * i ) - > processor ( ) ) {
our_processors . push_back ( ( * i ) - > processor ( ) ) ;
}
2007-06-27 16:23:48 -04:00
}
2009-07-12 20:26:28 -04:00
if ( _route - > reorder_processors ( our_processors ) ) {
2010-11-23 19:46:51 -05:00
/* Reorder failed, so report this to the user. As far as I can see this must be done
in an idle handler : it seems that the redisplay_processors ( ) that happens below destroys
widgets that were involved in the drag - and - drop on the processor list , which causes problems
when the drag is torn down after this handler function is finished .
*/
Glib : : signal_idle ( ) . connect_once ( sigc : : mem_fun ( * this , & ProcessorBox : : report_failed_reorder ) ) ;
}
}
2009-05-15 22:51:17 -04:00
2010-11-23 19:46:51 -05:00
void
ProcessorBox : : report_failed_reorder ( )
{
/* reorder failed, so redisplay */
2011-06-01 13:00:29 -04:00
2010-11-23 19:46:51 -05:00
redisplay_processors ( ) ;
2011-06-01 13:00:29 -04:00
2010-11-23 19:46:51 -05:00
/* now tell them about the problem */
2011-06-01 13:00:29 -04:00
2010-11-23 19:46:51 -05:00
ArdourDialog dialog ( _ ( " Plugin Incompatibility " ) ) ;
Label label ;
2011-06-01 13:00:29 -04:00
2010-11-23 19:46:51 -05:00
label . set_text ( _ ( " \
2010-01-25 15:34:09 -05:00
You cannot reorder these plugins / sends / inserts \ n \
2007-06-27 16:23:48 -04:00
in that way because the inputs and \ n \
2010-01-25 15:34:09 -05:00
outputs will not work correctly . " ));
2007-06-27 16:23:48 -04:00
2010-11-23 19:46:51 -05:00
dialog . get_vbox ( ) - > set_border_width ( 12 ) ;
dialog . get_vbox ( ) - > pack_start ( label ) ;
dialog . add_button ( Stock : : OK , RESPONSE_ACCEPT ) ;
2011-06-01 13:00:29 -04:00
2010-11-23 19:46:51 -05:00
dialog . set_name ( X_ ( " PluginIODialog " ) ) ;
dialog . set_modal ( true ) ;
dialog . show_all ( ) ;
2011-06-01 13:00:29 -04:00
2010-11-23 19:46:51 -05:00
dialog . run ( ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rename_processors ( )
{
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
ProcSelection to_be_renamed ;
2007-06-27 16:23:48 -04:00
get_selected_processors ( to_be_renamed ) ;
if ( to_be_renamed . empty ( ) ) {
return ;
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
for ( ProcSelection : : iterator i = to_be_renamed . begin ( ) ; i ! = to_be_renamed . end ( ) ; + + i ) {
2007-06-27 16:23:48 -04:00
rename_processor ( * i ) ;
}
}
2010-03-16 11:33:04 -04:00
bool
ProcessorBox : : can_cut ( ) const
{
2015-08-15 15:29:19 -04:00
vector < boost : : shared_ptr < Processor > > sel ;
2010-03-16 11:33:04 -04:00
2015-08-15 15:29:19 -04:00
get_selected_processors ( sel ) ;
2011-06-01 13:00:29 -04:00
2015-08-15 15:29:19 -04:00
/* cut_processors () does not cut inserts */
2010-03-16 11:33:04 -04:00
2015-08-15 15:29:19 -04:00
for ( vector < boost : : shared_ptr < Processor > > : : const_iterator i = sel . begin ( ) ; i ! = sel . end ( ) ; + + i ) {
2011-06-01 13:00:29 -04:00
2010-03-16 11:33:04 -04:00
if ( boost : : dynamic_pointer_cast < PluginInsert > ( ( * i ) ) ! = 0 | |
( boost : : dynamic_pointer_cast < Send > ( ( * i ) ) ! = 0 ) | |
( boost : : dynamic_pointer_cast < Return > ( ( * i ) ) ! = 0 ) ) {
2015-08-15 15:29:19 -04:00
return true ;
}
}
2011-06-01 13:00:29 -04:00
2015-08-15 15:29:19 -04:00
return false ;
}
bool
ProcessorBox : : stub_processor_selected ( ) const
{
vector < boost : : shared_ptr < Processor > > sel ;
get_selected_processors ( sel ) ;
for ( vector < boost : : shared_ptr < Processor > > : : const_iterator i = sel . begin ( ) ; i ! = sel . end ( ) ; + + i ) {
if ( boost : : dynamic_pointer_cast < UnknownProcessor > ( ( * i ) ) ! = 0 ) {
return true ;
}
}
return false ;
2010-03-16 11:33:04 -04:00
}
2009-07-15 16:29:02 -04:00
void
ProcessorBox : : cut_processors ( const ProcSelection & to_be_removed )
{
2007-06-27 16:23:48 -04:00
if ( to_be_removed . empty ( ) ) {
return ;
}
2009-07-15 16:29:02 -04:00
XMLNode * node = new XMLNode ( X_ ( " cut " ) ) ;
Route : : ProcessorList to_cut ;
2007-06-27 16:23:48 -04:00
no_processor_redisplay = true ;
2009-07-15 16:29:02 -04:00
for ( ProcSelection : : const_iterator i = to_be_removed . begin ( ) ; i ! = to_be_removed . end ( ) ; + + i ) {
// Cut only plugins, sends and returns
2008-12-12 09:43:24 -05:00
if ( boost : : dynamic_pointer_cast < PluginInsert > ( ( * i ) ) ! = 0 | |
2009-07-15 16:29:02 -04:00
( boost : : dynamic_pointer_cast < Send > ( ( * i ) ) ! = 0 ) | |
( boost : : dynamic_pointer_cast < Return > ( ( * i ) ) ! = 0 ) ) {
2007-08-01 18:18:46 -04:00
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( * i ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2010-08-17 22:20:15 -04:00
if ( w ) {
w - > hide ( ) ;
2007-06-27 16:23:48 -04:00
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2007-08-01 18:18:46 -04:00
XMLNode & child ( ( * i ) - > get_state ( ) ) ;
2009-07-15 16:29:02 -04:00
node - > add_child_nocopy ( child ) ;
to_cut . push_back ( * i ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
}
2007-06-27 16:23:48 -04:00
}
2009-10-14 12:10:01 -04:00
2009-07-15 16:29:02 -04:00
if ( _route - > remove_processors ( to_cut ) ! = 0 ) {
delete node ;
no_processor_redisplay = false ;
return ;
}
2007-08-01 18:18:46 -04:00
_rr_selection . set ( node ) ;
2007-06-27 16:23:48 -04:00
no_processor_redisplay = false ;
redisplay_processors ( ) ;
}
2009-07-15 16:29:02 -04:00
void
ProcessorBox : : copy_processors ( const ProcSelection & to_be_copied )
{
2007-06-27 16:23:48 -04:00
if ( to_be_copied . empty ( ) ) {
return ;
}
2009-07-15 16:29:02 -04:00
XMLNode * node = new XMLNode ( X_ ( " copy " ) ) ;
for ( ProcSelection : : const_iterator i = to_be_copied . begin ( ) ; i ! = to_be_copied . end ( ) ; + + i ) {
// Copy only plugins, sends, returns
2008-12-12 09:43:24 -05:00
if ( boost : : dynamic_pointer_cast < PluginInsert > ( ( * i ) ) ! = 0 | |
2009-07-15 16:29:02 -04:00
( boost : : dynamic_pointer_cast < Send > ( ( * i ) ) ! = 0 ) | |
( boost : : dynamic_pointer_cast < Return > ( ( * i ) ) ! = 0 ) ) {
2007-08-01 18:18:46 -04:00
node - > add_child_nocopy ( ( * i ) - > get_state ( ) ) ;
2007-06-27 16:23:48 -04:00
}
2016-03-15 12:40:53 -04:00
}
2007-06-27 16:23:48 -04:00
2007-08-01 18:18:46 -04:00
_rr_selection . set ( node ) ;
2007-06-27 16:23:48 -04:00
}
2009-07-15 16:29:02 -04:00
void
ProcessorBox : : delete_processors ( const ProcSelection & targets )
{
if ( targets . empty ( ) ) {
2007-06-27 16:23:48 -04:00
return ;
}
2009-05-15 22:51:17 -04:00
no_processor_redisplay = true ;
2009-07-15 16:29:02 -04:00
for ( ProcSelection : : const_iterator i = targets . begin ( ) ; i ! = targets . end ( ) ; + + i ) {
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( * i ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2010-08-17 22:20:15 -04:00
if ( w ) {
w - > hide ( ) ;
2007-06-27 16:23:48 -04:00
}
_route - > remove_processor ( * i ) ;
}
no_processor_redisplay = false ;
redisplay_processors ( ) ;
}
2009-05-15 22:51:17 -04:00
void
ProcessorBox : : delete_dragged_processors ( const list < boost : : shared_ptr < Processor > > & procs )
{
list < boost : : shared_ptr < Processor > > : : const_iterator x ;
no_processor_redisplay = true ;
for ( x = procs . begin ( ) ; x ! = procs . end ( ) ; + + x ) {
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( * x ) ;
2009-05-15 22:51:17 -04:00
2010-08-17 22:20:15 -04:00
if ( w ) {
w - > hide ( ) ;
2009-05-15 22:51:17 -04:00
}
2009-10-14 12:10:01 -04:00
2009-05-15 22:51:17 -04:00
_route - > remove_processor ( * x ) ;
}
no_processor_redisplay = false ;
redisplay_processors ( ) ;
}
2007-06-27 16:23:48 -04:00
gint
ProcessorBox : : idle_delete_processor ( boost : : weak_ptr < Processor > weak_processor )
{
boost : : shared_ptr < Processor > processor ( weak_processor . lock ( ) ) ;
if ( ! processor ) {
return false ;
}
/* NOT copied to _mixer.selection() */
no_processor_redisplay = true ;
_route - > remove_processor ( processor ) ;
no_processor_redisplay = false ;
redisplay_processors ( ) ;
return false ;
}
void
ProcessorBox : : rename_processor ( boost : : shared_ptr < Processor > processor )
{
ArdourPrompter name_prompter ( true ) ;
string result ;
2009-11-23 12:19:29 -05:00
name_prompter . set_title ( _ ( " Rename Processor " ) ) ;
name_prompter . set_prompt ( _ ( " New name: " ) ) ;
2007-06-27 16:23:48 -04:00
name_prompter . set_initial_text ( processor - > name ( ) ) ;
name_prompter . add_button ( _ ( " Rename " ) , Gtk : : RESPONSE_ACCEPT ) ;
name_prompter . set_response_sensitive ( Gtk : : RESPONSE_ACCEPT , false ) ;
name_prompter . show_all ( ) ;
switch ( name_prompter . run ( ) ) {
case Gtk : : RESPONSE_ACCEPT :
2009-10-01 21:49:57 -04:00
name_prompter . get_result ( result ) ;
if ( result . length ( ) ) {
2010-04-20 22:24:38 -04:00
int tries = 0 ;
string test = result ;
while ( tries < 100 ) {
if ( _session - > io_name_is_legal ( test ) ) {
result = test ;
break ;
}
tries + + ;
test = string_compose ( " %1-%2 " , result , tries ) ;
}
if ( tries < 100 ) {
processor - > set_name ( result ) ;
} else {
/* unlikely! */
ARDOUR_UI : : instance ( ) - > popup_error
( string_compose ( _ ( " At least 100 IO objects exist with a name like %1 - name not changed " ) , result ) ) ;
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
}
2007-06-27 16:23:48 -04:00
break ;
}
return ;
}
void
2007-08-01 18:18:46 -04:00
ProcessorBox : : paste_processors ( )
2007-06-27 16:23:48 -04:00
{
2007-08-01 18:18:46 -04:00
if ( _rr_selection . processors . empty ( ) ) {
return ;
}
2007-06-27 16:23:48 -04:00
2009-07-15 16:29:02 -04:00
paste_processor_state ( _rr_selection . processors . get_node ( ) . children ( ) , boost : : shared_ptr < Processor > ( ) ) ;
}
void
ProcessorBox : : paste_processors ( boost : : shared_ptr < Processor > before )
{
if ( _rr_selection . processors . empty ( ) ) {
return ;
}
2007-06-27 16:23:48 -04:00
2009-07-15 16:29:02 -04:00
paste_processor_state ( _rr_selection . processors . get_node ( ) . children ( ) , before ) ;
2007-06-27 16:23:48 -04:00
}
void
2009-07-15 16:29:02 -04:00
ProcessorBox : : paste_processor_state ( const XMLNodeList & nlist , boost : : shared_ptr < Processor > p )
2007-06-27 16:23:48 -04:00
{
2007-08-01 18:18:46 -04:00
XMLNodeConstIterator niter ;
2007-06-27 16:23:48 -04:00
list < boost : : shared_ptr < Processor > > copies ;
2007-08-01 18:18:46 -04:00
if ( nlist . empty ( ) ) {
return ;
}
for ( niter = nlist . begin ( ) ; niter ! = nlist . end ( ) ; + + niter ) {
2009-07-15 16:29:02 -04:00
2009-02-14 12:28:01 -05:00
XMLProperty const * type = ( * niter ) - > property ( " type " ) ;
2013-01-15 10:42:30 -05:00
XMLProperty const * role = ( * niter ) - > property ( " role " ) ;
2009-02-14 12:28:01 -05:00
assert ( type ) ;
2009-02-14 14:45:30 -05:00
boost : : shared_ptr < Processor > p ;
2007-08-01 18:18:46 -04:00
try {
2009-10-14 12:10:01 -04:00
if ( type - > value ( ) = = " meter " | |
2009-07-15 16:29:02 -04:00
type - > value ( ) = = " main-outs " | |
type - > value ( ) = = " amp " | |
2013-01-15 10:42:30 -05:00
type - > value ( ) = = " intreturn " ) {
/* do not paste meter, main outs, amp or internal returns */
2009-07-15 16:29:02 -04:00
continue ;
2013-01-15 10:42:30 -05:00
} else if ( type - > value ( ) = = " intsend " ) {
2015-10-05 10:17:49 -04:00
2013-01-15 10:42:30 -05:00
/* aux sends are OK, but those used for
* other purposes , are not .
*/
2015-10-05 10:17:49 -04:00
2013-01-18 12:35:34 -05:00
assert ( role ) ;
2013-01-15 10:42:30 -05:00
if ( role - > value ( ) ! = " Aux " ) {
continue ;
}
2014-01-13 04:48:37 -05:00
boost : : shared_ptr < Pannable > sendpan ( new Pannable ( * _session ) ) ;
2013-01-15 10:42:30 -05:00
XMLNode n ( * * niter ) ;
2014-06-22 18:48:47 -04:00
InternalSend * s = new InternalSend ( * _session , sendpan , _route - > mute_master ( ) ,
_route , boost : : shared_ptr < Route > ( ) , Delivery : : Aux ) ;
2013-01-15 10:42:30 -05:00
IOProcessor : : prepare_for_reset ( n , s - > name ( ) ) ;
if ( s - > set_state ( n , Stateful : : loading_state_version ) ) {
delete s ;
return ;
}
p . reset ( s ) ;
2009-07-15 16:29:02 -04:00
} else if ( type - > value ( ) = = " send " ) {
2009-10-14 12:10:01 -04:00
2014-01-13 04:50:49 -05:00
boost : : shared_ptr < Pannable > sendpan ( new Pannable ( * _session ) ) ;
2009-02-14 12:28:01 -05:00
XMLNode n ( * * niter ) ;
2014-01-14 10:56:17 -05:00
2014-01-13 17:21:30 -05:00
Send * s = new Send ( * _session , _route - > pannable ( ) , _route - > mute_master ( ) ) ;
2012-03-13 16:15:50 -04:00
2012-03-14 22:31:30 -04:00
IOProcessor : : prepare_for_reset ( n , s - > name ( ) ) ;
2015-10-05 10:17:49 -04:00
2010-03-24 10:01:31 -04:00
if ( s - > set_state ( n , Stateful : : loading_state_version ) ) {
delete s ;
return ;
}
p . reset ( s ) ;
2011-06-01 13:00:29 -04:00
2009-07-15 16:29:02 -04:00
} else if ( type - > value ( ) = = " return " ) {
2009-07-01 09:36:50 -04:00
2009-07-15 16:29:02 -04:00
XMLNode n ( * * niter ) ;
2012-03-14 22:31:30 -04:00
Return * r = new Return ( * _session ) ;
2012-03-13 16:15:50 -04:00
2012-03-14 22:31:30 -04:00
IOProcessor : : prepare_for_reset ( n , r - > name ( ) ) ;
2010-03-24 10:01:31 -04:00
if ( r - > set_state ( n , Stateful : : loading_state_version ) ) {
delete r ;
return ;
}
p . reset ( r ) ;
2009-10-14 12:10:01 -04:00
2011-03-01 10:24:44 -05:00
} else if ( type - > value ( ) = = " port " ) {
XMLNode n ( * * niter ) ;
2012-03-14 22:31:30 -04:00
PortInsert * pi = new PortInsert ( * _session , _route - > pannable ( ) , _route - > mute_master ( ) ) ;
2015-10-05 10:17:49 -04:00
2012-03-14 22:31:30 -04:00
IOProcessor : : prepare_for_reset ( n , pi - > name ( ) ) ;
2015-10-05 10:17:49 -04:00
2012-03-13 16:15:50 -04:00
if ( pi - > set_state ( n , Stateful : : loading_state_version ) ) {
2011-03-01 10:24:44 -05:00
return ;
}
2015-10-05 10:17:49 -04:00
2012-03-13 16:15:50 -04:00
p . reset ( pi ) ;
2009-02-14 12:28:01 -05:00
} else {
2009-07-15 16:29:02 -04:00
/* XXX its a bit limiting to assume that everything else
is a plugin .
*/
2010-03-31 21:24:13 -04:00
p . reset ( new PluginInsert ( * _session ) ) ;
2016-04-13 12:53:54 -04:00
/* we can't use RAII Stateful::ForceIDRegeneration
* because that ' d void copying the state and wrongly bump
* the state - version counter .
* we need to load the state ( incl external files ) first and
* only then update the ID )
*/
2015-07-10 16:09:18 -04:00
PBD : : ID id = p - > id ( ) ;
2016-04-13 12:53:54 -04:00
/* strip side-chain state (processor inside processor must be a side-chain)
* otherwise we ' ll end up with duplicate ports - names .
* ( this needs a better solution which retains connections )
* We really would want Stateful : : ForceIDRegeneration here : (
*/
XMLNode state ( * * niter ) ;
state . remove_nodes ( " Processor " ) ;
p - > set_state ( state , Stateful : : current_state_version ) ;
2015-07-10 16:09:18 -04:00
boost : : dynamic_pointer_cast < PluginInsert > ( p ) - > update_id ( id ) ;
2009-02-14 12:28:01 -05:00
}
2009-02-14 14:45:30 -05:00
copies . push_back ( p ) ;
2007-08-01 18:18:46 -04:00
}
2009-07-15 16:29:02 -04:00
2007-08-01 18:18:46 -04:00
catch ( . . . ) {
2012-11-13 10:11:07 -05:00
error < < _ ( " plugin insert constructor failed " ) < < endmsg ;
2007-08-01 18:18:46 -04:00
}
2007-06-27 16:23:48 -04:00
}
2009-05-13 17:34:09 -04:00
if ( copies . empty ( ) ) {
return ;
}
2009-07-15 16:29:02 -04:00
if ( _route - > add_processors ( copies , p ) ) {
2007-06-27 16:23:48 -04:00
string msg = _ (
" Copying the set of processors on the clipboard failed, \n \
probably because the I / O configuration of the plugins \ n \
could not match the configuration of this track . " );
MessageDialog am ( msg ) ;
am . run ( ) ;
}
}
void
2010-03-16 11:33:04 -04:00
ProcessorBox : : get_selected_processors ( ProcSelection & processors ) const
2007-06-27 16:23:48 -04:00
{
2010-03-16 11:33:04 -04:00
const list < ProcessorEntry * > selection = processor_display . selection ( ) ;
for ( list < ProcessorEntry * > : : const_iterator i = selection . begin ( ) ; i ! = selection . end ( ) ; + + i ) {
2009-11-25 09:37:20 -05:00
processors . push_back ( ( * i ) - > processor ( ) ) ;
}
2007-06-27 16:23:48 -04:00
}
void
2008-09-10 11:03:30 -04:00
ProcessorBox : : for_selected_processors ( void ( ProcessorBox : : * method ) ( boost : : shared_ptr < Processor > ) )
2007-06-27 16:23:48 -04:00
{
2009-11-25 09:37:20 -05:00
list < ProcessorEntry * > selection = processor_display . selection ( ) ;
for ( list < ProcessorEntry * > : : iterator i = selection . begin ( ) ; i ! = selection . end ( ) ; + + i ) {
( this - > * method ) ( ( * i ) - > processor ( ) ) ;
2007-06-27 16:23:48 -04:00
}
}
void
2011-11-16 12:40:16 -05:00
ProcessorBox : : all_visible_processors_active ( bool state )
2007-06-27 16:23:48 -04:00
{
2011-11-16 12:40:16 -05:00
_route - > all_visible_processors_active ( state ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : ab_plugins ( )
{
_route - > ab_plugins ( ab_direction ) ;
ab_direction = ! ab_direction ;
}
2008-09-10 11:03:30 -04:00
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : clear_processors ( )
{
string prompt ;
vector < string > choices ;
2009-07-15 16:29:02 -04:00
prompt = string_compose ( _ ( " Do you really want to remove all processors from %1? \n "
" (this cannot be undone) " ) , _route - > name ( ) ) ;
2009-10-14 12:10:01 -04:00
2009-07-15 16:29:02 -04:00
choices . push_back ( _ ( " Cancel " ) ) ;
choices . push_back ( _ ( " Yes, remove them all " ) ) ;
2009-12-22 20:26:33 -05:00
Gtkmm2ext : : Choice prompter ( _ ( " Remove processors " ) , prompt , choices ) ;
2009-07-15 16:29:02 -04:00
if ( prompter . run ( ) = = 1 ) {
_route - > clear_processors ( PreFader ) ;
_route - > clear_processors ( PostFader ) ;
}
}
void
ProcessorBox : : clear_processors ( Placement p )
{
string prompt ;
vector < string > choices ;
if ( p = = PreFader ) {
prompt = string_compose ( _ ( " Do you really want to remove all pre-fader processors from %1? \n "
" (this cannot be undone) " ) , _route - > name ( ) ) ;
2007-06-27 16:23:48 -04:00
} else {
2009-07-15 16:29:02 -04:00
prompt = string_compose ( _ ( " Do you really want to remove all post-fader processors from %1? \n "
" (this cannot be undone) " ) , _route - > name ( ) ) ;
2007-06-27 16:23:48 -04:00
}
choices . push_back ( _ ( " Cancel " ) ) ;
choices . push_back ( _ ( " Yes, remove them all " ) ) ;
2009-12-22 20:26:33 -05:00
Gtkmm2ext : : Choice prompter ( _ ( " Remove processors " ) , prompt , choices ) ;
2007-06-27 16:23:48 -04:00
if ( prompter . run ( ) = = 1 ) {
2009-07-15 16:29:02 -04:00
_route - > clear_processors ( p ) ;
2007-06-27 16:23:48 -04:00
}
}
2010-09-05 16:41:48 -04:00
bool
ProcessorBox : : processor_can_be_edited ( boost : : shared_ptr < Processor > processor )
{
boost : : shared_ptr < AudioTrack > at = boost : : dynamic_pointer_cast < AudioTrack > ( _route ) ;
if ( at & & at - > freeze_state ( ) = = AudioTrack : : Frozen ) {
return false ;
}
if (
2013-07-11 05:36:38 -04:00
boost : : dynamic_pointer_cast < Send > ( processor ) | |
2010-09-05 16:41:48 -04:00
boost : : dynamic_pointer_cast < Return > ( processor ) | |
boost : : dynamic_pointer_cast < PluginInsert > ( processor ) | |
boost : : dynamic_pointer_cast < PortInsert > ( processor )
) {
return true ;
}
return false ;
}
bool
ProcessorBox : : one_processor_can_be_edited ( )
{
list < ProcessorEntry * > selection = processor_display . selection ( ) ;
list < ProcessorEntry * > : : iterator i = selection . begin ( ) ;
while ( i ! = selection . end ( ) & & processor_can_be_edited ( ( * i ) - > processor ( ) ) = = false ) {
+ + i ;
}
return ( i ! = selection . end ( ) ) ;
}
2013-05-04 22:02:05 -04:00
Gtk : : Window *
2013-05-18 20:28:36 -04:00
ProcessorBox : : get_editor_window ( boost : : shared_ptr < Processor > processor , bool use_custom )
2007-06-27 16:23:48 -04:00
{
boost : : shared_ptr < Send > send ;
2011-01-10 18:58:57 -05:00
boost : : shared_ptr < InternalSend > internal_send ;
2009-05-07 13:31:18 -04:00
boost : : shared_ptr < Return > retrn ;
2008-09-10 11:03:30 -04:00
boost : : shared_ptr < PluginInsert > plugin_insert ;
boost : : shared_ptr < PortInsert > port_insert ;
Window * gidget = 0 ;
2007-06-27 16:23:48 -04:00
2013-10-14 11:14:38 -04:00
/* This method may or may not return a Window, but if it does not it
* will modify the parent mixer strip appearance layout to allow
* " editing " the @ param processor that was passed in .
*
* So for example , if the processor is an Amp ( gain ) , the parent strip
* will be forced back into a model where the fader controls the main gain .
* If the processor is a send , then we map the send controls onto the
* strip .
2015-10-04 14:51:05 -04:00
*
2013-10-14 11:14:38 -04:00
* Plugins and others will return a window for control .
*/
2007-06-27 16:23:48 -04:00
if ( boost : : dynamic_pointer_cast < AudioTrack > ( _route ) ! = 0 ) {
if ( boost : : dynamic_pointer_cast < AudioTrack > ( _route ) - > freeze_state ( ) = = AudioTrack : : Frozen ) {
2013-05-04 22:02:05 -04:00
return 0 ;
2007-06-27 16:23:48 -04:00
}
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2016-01-12 14:09:24 -05:00
if ( boost : : dynamic_pointer_cast < Amp > ( processor ) & & boost : : dynamic_pointer_cast < Amp > ( processor ) - > gain_control ( ) - > parameter ( ) . type ( ) = = GainAutomation ) {
2011-01-10 20:30:37 -05:00
2011-06-01 18:44:11 -04:00
if ( _parent_strip ) {
_parent_strip - > revert_to_default_display ( ) ;
}
2011-06-01 13:00:29 -04:00
2011-01-10 18:58:57 -05:00
} else if ( ( send = boost : : dynamic_pointer_cast < Send > ( processor ) ) ! = 0 ) {
if ( ! _session - > engine ( ) . connected ( ) ) {
2013-05-04 22:02:05 -04:00
return 0 ;
2011-01-10 18:58:57 -05:00
}
2011-11-09 14:25:30 -05:00
if ( boost : : dynamic_pointer_cast < InternalSend > ( processor ) = = 0 ) {
2013-06-07 17:50:13 -04:00
gidget = new SendUIWindow ( send , _session ) ;
2011-11-09 14:25:30 -05:00
}
2011-01-10 18:58:57 -05:00
2009-05-07 13:31:18 -04:00
} else if ( ( retrn = boost : : dynamic_pointer_cast < Return > ( processor ) ) ! = 0 ) {
2011-05-18 01:00:44 -04:00
if ( boost : : dynamic_pointer_cast < InternalReturn > ( retrn ) ) {
/* no GUI for these */
2013-05-04 22:02:05 -04:00
return 0 ;
2011-05-18 01:00:44 -04:00
}
2010-11-27 16:32:29 -05:00
2009-12-17 13:24:23 -05:00
if ( ! _session - > engine ( ) . connected ( ) ) {
2013-05-04 22:02:05 -04:00
return 0 ;
2009-05-07 13:31:18 -04:00
}
boost : : shared_ptr < Return > retrn = boost : : dynamic_pointer_cast < Return > ( processor ) ;
ReturnUIWindow * return_ui ;
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( retrn ) ;
2009-05-07 13:31:18 -04:00
2010-08-17 22:20:15 -04:00
if ( w = = 0 ) {
2009-05-07 13:31:18 -04:00
return_ui = new ReturnUIWindow ( retrn , _session ) ;
2009-10-19 13:25:37 -04:00
return_ui - > set_title ( retrn - > name ( ) ) ;
2010-08-17 22:20:15 -04:00
set_processor_ui ( send , return_ui ) ;
2009-05-07 13:31:18 -04:00
} else {
2010-08-17 22:20:15 -04:00
return_ui = dynamic_cast < ReturnUIWindow * > ( w ) ;
2009-05-07 13:31:18 -04:00
}
gidget = return_ui ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
} else if ( ( plugin_insert = boost : : dynamic_pointer_cast < PluginInsert > ( processor ) ) ! = 0 ) {
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
PluginUIWindow * plugin_ui ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
/* these are both allowed to be null */
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( plugin_insert ) ;
if ( w = = 0 ) {
2013-05-18 20:28:36 -04:00
plugin_ui = new PluginUIWindow ( plugin_insert , false , use_custom ) ;
2009-10-19 13:25:37 -04:00
plugin_ui - > set_title ( generate_processor_title ( plugin_insert ) ) ;
2010-08-17 22:20:15 -04:00
set_processor_ui ( plugin_insert , plugin_ui ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
} else {
2010-08-17 22:20:15 -04:00
plugin_ui = dynamic_cast < PluginUIWindow * > ( w ) ;
2008-09-10 11:03:30 -04:00
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
gidget = plugin_ui ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
} else if ( ( port_insert = boost : : dynamic_pointer_cast < PortInsert > ( processor ) ) ! = 0 ) {
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2009-12-17 13:24:23 -05:00
if ( ! _session - > engine ( ) . connected ( ) ) {
2013-09-17 22:25:21 -04:00
MessageDialog msg ( _ ( " Not connected to audio engine - no I/O changes are possible " ) ) ;
2007-06-27 16:23:48 -04:00
msg . run ( ) ;
2013-05-04 22:02:05 -04:00
return 0 ;
2007-06-27 16:23:48 -04:00
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2007-06-27 16:23:48 -04:00
PortInsertWindow * io_selector ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( port_insert ) ;
if ( w = = 0 ) {
2009-12-17 13:24:23 -05:00
io_selector = new PortInsertWindow ( _session , port_insert ) ;
2010-08-17 22:20:15 -04:00
set_processor_ui ( port_insert , io_selector ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2007-06-27 16:23:48 -04:00
} else {
2010-08-17 22:20:15 -04:00
io_selector = dynamic_cast < PortInsertWindow * > ( w ) ;
2007-06-27 16:23:48 -04:00
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2008-09-10 11:03:30 -04:00
gidget = io_selector ;
}
2007-06-27 16:23:48 -04:00
2013-05-04 22:02:05 -04:00
return gidget ;
2007-06-27 16:23:48 -04:00
}
2013-05-04 22:02:05 -04:00
Gtk : : Window *
ProcessorBox : : get_generic_editor_window ( boost : : shared_ptr < Processor > processor )
2012-01-21 17:10:07 -05:00
{
boost : : shared_ptr < PluginInsert > plugin_insert
= boost : : dynamic_pointer_cast < PluginInsert > ( processor ) ;
2013-05-04 22:02:05 -04:00
2012-01-21 17:10:07 -05:00
if ( ! plugin_insert ) {
2013-05-04 22:02:05 -04:00
return 0 ;
2012-01-21 17:10:07 -05:00
}
2013-05-04 22:02:05 -04:00
PluginUIWindow * win = new PluginUIWindow ( plugin_insert , true , false ) ;
win - > set_title ( generate_processor_title ( plugin_insert ) ) ;
2012-01-21 17:10:07 -05:00
2013-05-04 22:02:05 -04:00
return win ;
2012-01-21 17:10:07 -05:00
}
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : register_actions ( )
{
2016-03-15 12:40:53 -04:00
processor_box_actions = myactions . create_action_group ( X_ ( " ProcessorMenu " ) ) ;
2007-06-27 16:23:48 -04:00
Glib : : RefPtr < Action > act ;
/* new stuff */
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " newplugin " ) , _ ( " New Plugin " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_choose_plugin ) ) ;
2007-06-27 16:23:48 -04:00
2016-03-15 12:40:53 -04:00
act = myactions . register_action ( processor_box_actions , X_ ( " newinsert " ) , _ ( " New Insert " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_choose_insert ) ) ;
2013-09-04 12:49:52 -04:00
ActionManager : : engine_sensitive_actions . push_back ( act ) ;
2016-03-15 12:40:53 -04:00
act = myactions . register_action ( processor_box_actions , X_ ( " newsend " ) , _ ( " New External Send ... " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_choose_send ) ) ;
2013-09-04 12:49:52 -04:00
ActionManager : : engine_sensitive_actions . push_back ( act ) ;
2009-11-18 23:25:46 -05:00
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " newaux " ) , _ ( " New Aux Send ... " ) ) ;
2007-06-27 16:23:48 -04:00
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " controls " ) , _ ( " Controls " ) ) ;
myactions . register_action ( processor_box_actions , X_ ( " send_options " ) , _ ( " Send Options " ) ) ;
2012-01-20 13:02:48 -05:00
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " clear " ) , _ ( " Clear (all) " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_clear ) ) ;
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " clear_pre " ) , _ ( " Clear (pre-fader) " ) ,
2009-07-15 16:29:02 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_clear_pre ) ) ;
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " clear_post " ) , _ ( " Clear (post-fader) " ) ,
2009-07-15 16:29:02 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_clear_post ) ) ;
2007-06-27 16:23:48 -04:00
/* standard editing stuff */
2015-08-08 08:36:29 -04:00
2016-03-15 12:40:53 -04:00
cut_action = myactions . register_action ( processor_box_actions , X_ ( " cut " ) , _ ( " Cut " ) ,
2015-08-01 23:40:55 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_cut ) ) ;
2016-03-15 12:40:53 -04:00
copy_action = myactions . register_action ( processor_box_actions , X_ ( " copy " ) , _ ( " Copy " ) ,
2015-08-01 23:40:55 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_copy ) ) ;
2016-03-15 12:40:53 -04:00
delete_action = myactions . register_action ( processor_box_actions , X_ ( " delete " ) , _ ( " Delete " ) ,
2015-08-01 23:40:55 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_delete ) ) ;
2015-10-26 14:35:06 -04:00
2015-08-01 23:40:55 -04:00
ActionManager : : plugin_selection_sensitive_actions . push_back ( cut_action ) ;
ActionManager : : plugin_selection_sensitive_actions . push_back ( copy_action ) ;
ActionManager : : plugin_selection_sensitive_actions . push_back ( delete_action ) ;
2015-10-26 14:35:06 -04:00
2016-03-15 12:40:53 -04:00
paste_action = myactions . register_action ( processor_box_actions , X_ ( " paste " ) , _ ( " Paste " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_paste ) ) ;
2016-03-15 12:40:53 -04:00
rename_action = myactions . register_action ( processor_box_actions , X_ ( " rename " ) , _ ( " Rename " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_rename ) ) ;
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " selectall " ) , _ ( " Select All " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_select_all ) ) ;
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " deselectall " ) , _ ( " Deselect All " ) ,
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_deselect_all ) ) ;
2009-11-30 08:13:57 -05:00
/* activation etc. */
2009-11-27 20:51:47 -05:00
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " activate_all " ) , _ ( " Activate All " ) ,
2011-05-18 01:00:44 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_activate_all ) ) ;
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " deactivate_all " ) , _ ( " Deactivate All " ) ,
2011-05-18 01:00:44 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_deactivate_all ) ) ;
2016-03-15 12:40:53 -04:00
myactions . register_action ( processor_box_actions , X_ ( " ab_plugins " ) , _ ( " A/B Plugins " ) ,
2011-05-18 01:00:44 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_ab_plugins ) ) ;
2007-06-27 16:23:48 -04:00
2016-03-27 15:35:42 -04:00
manage_pins_action = myactions . register_action (
2016-04-04 07:56:34 -04:00
processor_box_actions , X_ ( " manage-pins " ) , _ ( " Pin Connections... " ) ,
2016-03-27 15:35:42 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_manage_pins ) ) ;
2007-06-27 16:23:48 -04:00
/* show editors */
2016-03-15 12:40:53 -04:00
edit_action = myactions . register_action (
processor_box_actions , X_ ( " edit " ) , _ ( " Edit... " ) ,
2011-05-18 01:00:44 -04:00
sigc : : ptr_fun ( ProcessorBox : : rb_edit ) ) ;
2016-03-15 12:40:53 -04:00
edit_generic_action = myactions . register_action (
processor_box_actions , X_ ( " edit-generic " ) , _ ( " Edit with generic controls... " ) ,
2012-01-21 17:10:07 -05:00
sigc : : ptr_fun ( ProcessorBox : : rb_edit_generic ) ) ;
2016-03-15 12:40:53 -04:00
load_bindings ( ) ;
2007-06-27 16:23:48 -04:00
}
2012-01-21 17:10:07 -05:00
void
ProcessorBox : : rb_edit_generic ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2013-05-04 22:02:05 -04:00
_current_processor_box - > for_selected_processors ( & ProcessorBox : : generic_edit_processor ) ;
2012-01-21 17:10:07 -05:00
}
2007-06-27 16:23:48 -04:00
void
2009-11-30 08:13:57 -05:00
ProcessorBox : : rb_ab_plugins ( )
2007-06-27 16:23:48 -04:00
{
if ( _current_processor_box = = 0 ) {
return ;
}
2009-11-30 08:13:57 -05:00
_current_processor_box - > ab_plugins ( ) ;
2007-06-27 16:23:48 -04:00
}
2016-03-27 15:35:42 -04:00
void
ProcessorBox : : rb_manage_pins ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > for_selected_processors ( & ProcessorBox : : manage_pins ) ;
}
2007-06-27 16:23:48 -04:00
void
2009-11-30 08:13:57 -05:00
ProcessorBox : : rb_choose_plugin ( )
2007-06-27 16:23:48 -04:00
{
if ( _current_processor_box = = 0 ) {
return ;
}
2009-11-30 08:13:57 -05:00
_current_processor_box - > choose_plugin ( ) ;
2007-06-27 16:23:48 -04:00
}
void
2009-11-30 08:13:57 -05:00
ProcessorBox : : rb_choose_insert ( )
2007-06-27 16:23:48 -04:00
{
if ( _current_processor_box = = 0 ) {
return ;
}
2009-11-30 08:13:57 -05:00
_current_processor_box - > choose_insert ( ) ;
2007-06-27 16:23:48 -04:00
}
2009-05-07 13:31:18 -04:00
void
2009-11-30 08:13:57 -05:00
ProcessorBox : : rb_choose_send ( )
2009-05-07 13:31:18 -04:00
{
if ( _current_processor_box = = 0 ) {
return ;
}
2009-11-30 08:13:57 -05:00
_current_processor_box - > choose_send ( ) ;
2009-05-07 13:31:18 -04:00
}
2009-11-18 23:25:46 -05:00
void
ProcessorBox : : rb_choose_aux ( boost : : weak_ptr < Route > wr )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > choose_aux ( wr ) ;
}
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : rb_clear ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > clear_processors ( ) ;
}
2009-07-15 16:29:02 -04:00
void
ProcessorBox : : rb_clear_pre ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > clear_processors ( PreFader ) ;
}
void
ProcessorBox : : rb_clear_post ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > clear_processors ( PostFader ) ;
}
2007-06-27 16:23:48 -04:00
void
ProcessorBox : : rb_cut ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-04 13:53:21 -04:00
_current_processor_box - > processor_operation ( ProcessorsCut ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_delete ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-04 13:53:21 -04:00
_current_processor_box - > processor_operation ( ProcessorsDelete ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_copy ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-04 13:53:21 -04:00
_current_processor_box - > processor_operation ( ProcessorsCopy ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_paste ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-04 13:53:21 -04:00
_current_processor_box - > processor_operation ( ProcessorsPaste ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_rename ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > rename_processors ( ) ;
}
void
ProcessorBox : : rb_select_all ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-04 13:53:21 -04:00
_current_processor_box - > processor_operation ( ProcessorsSelectAll ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_deselect_all ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
_current_processor_box - > deselect_all_processors ( ) ;
}
void
ProcessorBox : : rb_activate_all ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-16 12:40:16 -05:00
_current_processor_box - > all_visible_processors_active ( true ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_deactivate_all ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2011-11-16 12:40:16 -05:00
_current_processor_box - > all_visible_processors_active ( false ) ;
2007-06-27 16:23:48 -04:00
}
void
ProcessorBox : : rb_edit ( )
{
if ( _current_processor_box = = 0 ) {
return ;
}
2013-05-04 22:02:05 -04:00
_current_processor_box - > for_selected_processors ( & ProcessorBox : : edit_processor ) ;
}
2013-07-11 05:36:38 -04:00
bool
ProcessorBox : : edit_aux_send ( boost : : shared_ptr < Processor > processor )
{
if ( boost : : dynamic_pointer_cast < InternalSend > ( processor ) = = 0 ) {
return false ;
}
if ( _parent_strip ) {
boost : : shared_ptr < Send > send = boost : : dynamic_pointer_cast < Send > ( processor ) ;
if ( _parent_strip - > current_delivery ( ) = = send ) {
_parent_strip - > revert_to_default_display ( ) ;
} else {
_parent_strip - > show_send ( send ) ;
}
}
return true ;
}
2013-05-04 22:02:05 -04:00
void
ProcessorBox : : edit_processor ( boost : : shared_ptr < Processor > processor )
{
if ( ! processor ) {
return ;
}
2013-07-11 05:36:38 -04:00
if ( edit_aux_send ( processor ) ) {
return ;
}
2013-05-04 22:02:05 -04:00
ProcessorWindowProxy * proxy = find_window_proxy ( processor ) ;
if ( proxy ) {
2013-06-06 17:55:08 -04:00
proxy - > set_custom_ui_mode ( true ) ;
2015-08-04 14:30:41 -04:00
proxy - > show_the_right_window ( ) ;
2013-05-04 22:02:05 -04:00
}
}
void
ProcessorBox : : generic_edit_processor ( boost : : shared_ptr < Processor > processor )
{
if ( ! processor ) {
return ;
}
2013-07-11 05:36:38 -04:00
if ( edit_aux_send ( processor ) ) {
return ;
}
2013-05-04 22:02:05 -04:00
ProcessorWindowProxy * proxy = find_window_proxy ( processor ) ;
if ( proxy ) {
2013-05-18 20:28:36 -04:00
proxy - > set_custom_ui_mode ( false ) ;
2015-08-04 14:30:41 -04:00
proxy - > show_the_right_window ( ) ;
2013-05-04 22:02:05 -04:00
}
2007-06-27 16:23:48 -04:00
}
2016-03-27 15:35:42 -04:00
void
ProcessorBox : : manage_pins ( boost : : shared_ptr < Processor > processor )
{
if ( ! processor ) {
return ;
}
PluginPinWindowProxy * proxy = processor - > pinmgr_proxy ( ) ;
if ( proxy ) {
proxy - > get ( true ) ;
proxy - > present ( ) ;
}
}
2007-06-27 16:23:48 -04:00
void
2010-02-19 13:09:08 -05:00
ProcessorBox : : route_property_changed ( const PropertyChange & what_changed )
2007-06-27 16:23:48 -04:00
{
2010-02-19 13:09:08 -05:00
if ( ! what_changed . contains ( ARDOUR : : Properties : : name ) ) {
return ;
}
ENSURE_GUI_THREAD ( * this , & ProcessorBox : : route_property_changed , what_changed ) ;
2009-03-07 09:06:19 -05:00
boost : : shared_ptr < Processor > processor ;
boost : : shared_ptr < PluginInsert > plugin_insert ;
boost : : shared_ptr < Send > send ;
2009-11-25 09:37:20 -05:00
list < ProcessorEntry * > children = processor_display . children ( ) ;
2009-03-07 09:06:19 -05:00
2009-11-25 09:37:20 -05:00
for ( list < ProcessorEntry * > : : iterator iter = children . begin ( ) ; iter ! = children . end ( ) ; + + iter ) {
2009-03-07 09:06:19 -05:00
2016-03-15 12:40:53 -04:00
processor = ( * iter ) - > processor ( ) ;
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
2012-01-08 20:33:24 -05:00
if ( ! processor ) {
continue ;
}
2010-08-17 22:20:15 -04:00
Window * w = get_processor_ui ( processor ) ;
2009-03-07 09:06:19 -05:00
2010-08-17 22:20:15 -04:00
if ( ! w ) {
2009-03-07 09:06:19 -05:00
continue ;
}
2008-09-10 11:03:30 -04:00
2009-03-07 09:06:19 -05:00
/* rename editor windows for sends and plugins */
2007-06-27 16:23:48 -04:00
2009-03-07 09:06:19 -05:00
if ( ( send = boost : : dynamic_pointer_cast < Send > ( processor ) ) ! = 0 ) {
2010-08-17 22:20:15 -04:00
w - > set_title ( send - > name ( ) ) ;
2009-03-07 09:06:19 -05:00
} else if ( ( plugin_insert = boost : : dynamic_pointer_cast < PluginInsert > ( processor ) ) ! = 0 ) {
2010-08-17 22:20:15 -04:00
w - > set_title ( generate_processor_title ( plugin_insert ) ) ;
2009-03-07 09:06:19 -05:00
}
2007-06-27 16:23:48 -04:00
}
}
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
string
2007-06-27 16:23:48 -04:00
ProcessorBox : : generate_processor_title ( boost : : shared_ptr < PluginInsert > pi )
{
2008-01-19 00:06:33 -05:00
string maker = pi - > plugin ( ) - > maker ( ) ? pi - > plugin ( ) - > maker ( ) : " " ;
2007-06-27 16:23:48 -04:00
string : : size_type email_pos ;
if ( ( email_pos = maker . find_first_of ( ' < ' ) ) ! = string : : npos ) {
maker = maker . substr ( 0 , email_pos - 1 ) ;
}
if ( maker . length ( ) > 32 ) {
maker = maker . substr ( 0 , 32 ) ;
maker + = " ... " ;
}
2013-10-14 11:14:38 -04:00
SessionObject * owner = pi - > owner ( ) ;
if ( owner ) {
return string_compose ( _ ( " %1: %2 (by %3) " ), owner->name(), pi->name(), maker) ;
} else {
2013-11-22 12:22:55 -05:00
return string_compose ( _ ( " %1 (by %2) " ), pi->name(), maker) ;
2013-10-14 11:14:38 -04:00
}
2007-06-27 16:23:48 -04:00
}
2010-08-17 22:20:15 -04:00
/** @param p Processor.
* @ return the UI window for \ a p .
*/
Window *
ProcessorBox : : get_processor_ui ( boost : : shared_ptr < Processor > p ) const
{
2014-11-28 19:35:49 -05:00
ProcessorWindowProxy * wp = p - > window_proxy ( ) ;
if ( wp ) {
return wp - > get ( ) ;
2010-08-17 22:20:15 -04:00
}
2010-09-05 16:59:10 -04:00
return 0 ;
2010-08-17 22:20:15 -04:00
}
/** Make a note of the UI window that a processor is using.
* @ param p Processor .
* @ param w UI window .
*/
void
ProcessorBox : : set_processor_ui ( boost : : shared_ptr < Processor > p , Gtk : : Window * w )
{
2014-11-28 19:35:49 -05:00
assert ( p - > window_proxy ( ) ) ;
2011-05-18 01:00:44 -04:00
p - > set_ui ( w ) ;
2014-11-28 19:35:49 -05:00
p - > window_proxy ( ) - > use_window ( * w ) ;
2010-08-17 22:20:15 -04:00
}
2011-01-04 18:26:59 -05:00
void
ProcessorBox : : mixer_strip_delivery_changed ( boost : : weak_ptr < Delivery > w )
{
boost : : shared_ptr < Delivery > d = w . lock ( ) ;
if ( ! d ) {
return ;
}
list < ProcessorEntry * > children = processor_display . children ( ) ;
list < ProcessorEntry * > : : const_iterator i = children . begin ( ) ;
while ( i ! = children . end ( ) & & ( * i ) - > processor ( ) ! = d ) {
+ + i ;
}
if ( i = = children . end ( ) ) {
processor_display . set_active ( 0 ) ;
} else {
processor_display . set_active ( * i ) ;
}
}
2012-01-20 13:02:48 -05:00
/** Called to repair the damage of Editor::show_window doing a show_all() */
2011-02-09 21:44:56 -05:00
void
ProcessorBox : : hide_things ( )
{
list < ProcessorEntry * > c = processor_display . children ( ) ;
for ( list < ProcessorEntry * > : : iterator i = c . begin ( ) ; i ! = c . end ( ) ; + + i ) {
( * i ) - > hide_things ( ) ;
}
}
2011-10-19 12:53:36 -04:00
void
ProcessorBox : : processor_menu_unmapped ( )
{
processor_display . remove_placeholder ( ) ;
2016-03-15 12:38:19 -04:00
/* make all possibly-desensitized actions sensitive again so that
they be activated by other means ( e . g . bindings )
*/
ActionManager : : set_sensitive ( ActionManager : : plugin_selection_sensitive_actions , true ) ;
2011-10-19 12:53:36 -04:00
}
2012-01-20 13:02:48 -05:00
XMLNode *
ProcessorBox : : entry_gui_object_state ( ProcessorEntry * entry )
{
if ( ! _parent_strip ) {
return 0 ;
}
GUIObjectState & st = _parent_strip - > gui_object_state ( ) ;
2015-10-05 10:17:49 -04:00
2012-01-20 13:02:48 -05:00
XMLNode * strip = st . get_or_add_node ( _parent_strip - > state_id ( ) ) ;
assert ( strip ) ;
return st . get_or_add_node ( strip , entry - > state_id ( ) ) ;
}
void
ProcessorBox : : update_gui_object_state ( ProcessorEntry * entry )
{
XMLNode * proc = entry_gui_object_state ( entry ) ;
if ( ! proc ) {
return ;
}
/* XXX: this is a bit inefficient; we just remove all child nodes and re-add them */
proc - > remove_nodes_and_delete ( X_ ( " Object " ) ) ;
entry - > add_control_state ( proc ) ;
}
2013-10-13 22:41:17 -04:00
bool
ProcessorBox : : is_editor_mixer_strip ( ) const
{
return _parent_strip & & ! _parent_strip - > mixer_owned ( ) ;
}
2013-05-04 22:02:05 -04:00
ProcessorWindowProxy : : ProcessorWindowProxy ( string const & name , ProcessorBox * box , boost : : weak_ptr < Processor > processor )
2013-05-07 22:09:16 -04:00
: WM : : ProxyBase ( name , string ( ) )
2010-08-17 22:20:15 -04:00
, _processor_box ( box )
, _processor ( processor )
2013-05-04 22:02:05 -04:00
, is_custom ( false )
2013-05-18 20:28:36 -04:00
, want_custom ( false )
2010-08-17 22:20:15 -04:00
{
2013-10-13 22:41:17 -04:00
boost : : shared_ptr < Processor > p = _processor . lock ( ) ;
if ( ! p ) {
return ;
}
p - > DropReferences . connect ( going_away_connection , MISSING_INVALIDATOR , boost : : bind ( & ProcessorWindowProxy : : processor_going_away , this ) , gui_context ( ) ) ;
}
ProcessorWindowProxy : : ~ ProcessorWindowProxy ( )
{
/* processor window proxies do not own the windows they create with
* : : get ( ) , so set _window to null before the normal WindowProxy method
* deletes it .
*/
_window = 0 ;
}
2010-08-17 22:20:15 -04:00
2013-10-13 22:41:17 -04:00
void
ProcessorWindowProxy : : processor_going_away ( )
{
delete _window ;
_window = 0 ;
2014-11-28 19:35:49 -05:00
WM : : Manager : : instance ( ) . remove ( this ) ;
2013-10-13 22:41:17 -04:00
/* should be no real reason to do this, since the object that would
send DropReferences is about to be deleted , but lets do it anyway .
*/
going_away_connection . disconnect ( ) ;
2010-08-17 22:20:15 -04:00
}
2013-05-04 22:02:05 -04:00
ARDOUR : : SessionHandlePtr *
2015-10-04 14:51:05 -04:00
ProcessorWindowProxy : : session_handle ( )
2013-05-04 22:02:05 -04:00
{
/* we don't care */
return 0 ;
}
2010-08-17 22:20:15 -04:00
2013-05-21 15:23:10 -04:00
XMLNode &
2015-07-07 22:12:21 -04:00
ProcessorWindowProxy : : get_state ( )
2013-05-21 15:23:10 -04:00
{
XMLNode * node ;
node = & ProxyBase : : get_state ( ) ;
node - > add_property ( X_ ( " custom-ui " ) , is_custom ? X_ ( " yes " ) : X_ ( " no " ) ) ;
return * node ;
}
2015-07-07 22:12:21 -04:00
int
ProcessorWindowProxy : : set_state ( const XMLNode & node , int /*version*/ )
2013-05-21 15:23:10 -04:00
{
XMLNodeList children = node . children ( ) ;
XMLNodeList : : const_iterator i = children . begin ( ) ;
while ( i ! = children . end ( ) ) {
2016-05-04 23:09:37 -04:00
XMLProperty const * prop = ( * i ) - > property ( X_ ( " name " ) ) ;
2013-05-21 15:23:10 -04:00
if ( ( * i ) - > name ( ) = = X_ ( " Window " ) & & prop & & prop - > value ( ) = = _name ) {
break ;
}
+ + i ;
}
if ( i ! = children . end ( ) ) {
2016-05-04 23:09:37 -04:00
XMLProperty const * prop ;
2013-05-21 15:23:10 -04:00
if ( ( prop = ( * i ) - > property ( X_ ( " custom-ui " ) ) ) ! = 0 ) {
want_custom = PBD : : string_is_affirmative ( prop - > value ( ) ) ;
}
}
2015-07-07 22:12:21 -04:00
return ProxyBase : : set_state ( node , 0 ) ;
2013-05-21 15:23:10 -04:00
}
2013-05-04 22:02:05 -04:00
Gtk : : Window *
ProcessorWindowProxy : : get ( bool create )
2010-08-17 22:20:15 -04:00
{
boost : : shared_ptr < Processor > p = _processor . lock ( ) ;
2013-05-04 22:02:05 -04:00
2010-08-17 22:20:15 -04:00
if ( ! p ) {
2013-05-04 22:02:05 -04:00
return 0 ;
2010-08-17 22:20:15 -04:00
}
2013-05-18 20:28:36 -04:00
if ( _window & & ( is_custom ! = want_custom ) ) {
2013-05-04 22:02:05 -04:00
/* drop existing window - wrong type */
drop_window ( ) ;
}
if ( ! _window ) {
if ( ! create ) {
return 0 ;
}
2015-10-05 10:17:49 -04:00
2013-05-18 20:28:36 -04:00
is_custom = want_custom ;
_window = _processor_box - > get_editor_window ( p , is_custom ) ;
2010-08-17 22:20:15 -04:00
2013-05-04 22:02:05 -04:00
if ( _window ) {
setup ( ) ;
}
2016-04-19 12:24:35 -04:00
_window - > show_all ( ) ;
2013-05-04 22:02:05 -04:00
}
return _window ;
2010-08-17 22:20:15 -04:00
}
2011-01-04 18:26:59 -05:00
2013-05-04 22:02:05 -04:00
void
2015-08-04 14:30:41 -04:00
ProcessorWindowProxy : : show_the_right_window ( )
2013-05-04 22:02:05 -04:00
{
2013-05-18 20:28:36 -04:00
if ( _window & & ( is_custom ! = want_custom ) ) {
2013-05-04 22:02:05 -04:00
/* drop existing window - wrong type */
drop_window ( ) ;
2015-08-04 14:30:41 -04:00
get ( true ) ;
setup ( ) ;
assert ( _window ) ;
is_custom = want_custom ;
2013-05-04 22:02:05 -04:00
}
2015-08-04 14:30:41 -04:00
toggle ( ) ;
2013-05-04 22:02:05 -04:00
}
2016-03-15 12:40:53 -04:00
2016-03-27 15:35:42 -04:00
PluginPinWindowProxy : : PluginPinWindowProxy ( std : : string const & name , boost : : weak_ptr < ARDOUR : : Processor > processor )
: WM : : ProxyBase ( name , string ( ) )
, _processor ( processor )
{
boost : : shared_ptr < Processor > p = _processor . lock ( ) ;
if ( ! p ) {
return ;
}
p - > DropReferences . connect ( going_away_connection , MISSING_INVALIDATOR , boost : : bind ( & PluginPinWindowProxy : : processor_going_away , this ) , gui_context ( ) ) ;
}
PluginPinWindowProxy : : ~ PluginPinWindowProxy ( )
{
_window = 0 ;
}
2016-04-02 23:21:40 -04:00
ARDOUR : : SessionHandlePtr *
PluginPinWindowProxy : : session_handle ( )
{
ArdourWindow * aw = dynamic_cast < ArdourWindow * > ( _window ) ;
if ( aw ) { return aw ; }
return 0 ;
}
2016-03-27 15:35:42 -04:00
Gtk : : Window *
PluginPinWindowProxy : : get ( bool create )
{
boost : : shared_ptr < Processor > p = _processor . lock ( ) ;
boost : : shared_ptr < PluginInsert > pi = boost : : dynamic_pointer_cast < PluginInsert > ( p ) ;
if ( ! p | | ! pi ) {
return 0 ;
}
if ( ! _window ) {
if ( ! create ) {
return 0 ;
}
_window = new PluginPinDialog ( pi ) ;
2016-04-02 23:21:40 -04:00
ArdourWindow * aw = dynamic_cast < ArdourWindow * > ( _window ) ;
if ( aw ) {
aw - > set_session ( _session ) ;
}
2016-04-19 12:24:35 -04:00
_window - > show_all ( ) ;
2016-03-27 15:35:42 -04:00
}
return _window ;
}
void
PluginPinWindowProxy : : processor_going_away ( )
{
delete _window ;
_window = 0 ;
WM : : Manager : : instance ( ) . remove ( this ) ;
going_away_connection . disconnect ( ) ;
}
2016-03-15 12:40:53 -04:00
void
ProcessorBox : : load_bindings ( )
{
2016-03-15 21:25:02 -04:00
bindings = Bindings : : get_bindings ( X_ ( " Processor Box " ) , myactions ) ;
2016-03-15 12:40:53 -04:00
}