2 Copyright (C) 2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <sigc++/bind.h>
24 #include <gtkmm/frame.h>
25 #include <gtkmm/image.h>
26 #include <gtkmm/scrolledwindow.h>
28 #include <libgnomecanvasmm/line.h>
30 #include "pbd/memento_command.h"
31 #include "ardour/automation_list.h"
32 #include "evoral/Curve.hpp"
33 #include "ardour/crossfade.h"
34 #include "ardour/session.h"
35 #include "ardour/auditioner.h"
36 #include "ardour/audioplaylist.h"
37 #include "ardour/audiosource.h"
38 #include "ardour/region_factory.h"
39 #include "ardour/profile.h"
41 #include <gtkmm2ext/gtk_ui.h>
43 #include "ardour_ui.h"
44 #include "crossfade_edit.h"
45 #include "rgb_macros.h"
48 #include "gui_thread.h"
49 #include "canvas_impl.h"
50 #include "simplerect.h"
55 using namespace ARDOUR
;
58 using namespace Editing
;
60 using Gtkmm2ext::Keyboard
;
64 const int32_t CrossfadeEditor::Point::size
= 7;
65 const double CrossfadeEditor::canvas_border
= 10;
66 CrossfadeEditor::Presets
* CrossfadeEditor::fade_in_presets
= 0;
67 CrossfadeEditor::Presets
* CrossfadeEditor::fade_out_presets
= 0;
69 CrossfadeEditor::Half::Half ()
71 , normative_curve (Evoral::Parameter(GainAutomation
))
72 , gain_curve (Evoral::Parameter(GainAutomation
))
76 CrossfadeEditor::CrossfadeEditor (Session
* s
, boost::shared_ptr
<Crossfade
> xf
, double my
, double mxy
)
77 : ArdourDialog (_("Edit Crossfade")),
79 clear_button (_("Clear")),
80 revert_button (_("Reset")),
81 audition_both_button (_("Fade")),
82 audition_left_dry_button (_("Out (dry)")),
83 audition_left_button (_("Out")),
84 audition_right_dry_button (_("In (dry)")),
85 audition_right_button (_("In")),
87 preroll_button (_("With Pre-roll")),
88 postroll_button (_("With Post-roll")),
94 fade_out_table (3, 3),
96 select_in_button (_("Fade In")),
97 select_out_button (_("Fade Out")),
99 _peaks_ready_connection (0)
104 set_wmclass (X_("ardour_automationedit"), PROGRAM_NAME
);
105 set_name ("CrossfadeEditWindow");
106 set_position (Gtk::WIN_POS_MOUSE
);
108 add_accel_group (ActionManager::ui_manager
->get_accel_group());
110 add_events (Gdk::KEY_PRESS_MASK
|Gdk::KEY_RELEASE_MASK
|Gdk::POINTER_MOTION_MASK
);
112 RadioButtonGroup sel_but_group
= select_in_button
.get_group();
113 select_out_button
.set_group (sel_but_group
);
114 select_out_button
.set_mode (false);
115 select_in_button
.set_mode (false);
117 get_action_area()->set_layout(BUTTONBOX_SPREAD
);
118 get_action_area()->pack_start(clear_button
);
119 get_action_area()->pack_start(revert_button
);
120 cancel_button
= add_button ("Cancel", RESPONSE_CANCEL
);
121 ok_button
= add_button ("OK", RESPONSE_ACCEPT
);
123 if (fade_in_presets
== 0) {
127 point_grabbed
= false;
130 canvas
= new ArdourCanvas::CanvasAA ();
131 canvas
->signal_size_allocate().connect (sigc::mem_fun(*this, &CrossfadeEditor::canvas_allocation
));
132 canvas
->set_size_request (425, 200);
134 toplevel
= new ArdourCanvas::SimpleRect (*(canvas
->root()));
135 toplevel
->property_x1() = 0.0;
136 toplevel
->property_y1() = 0.0;
137 toplevel
->property_x2() = 10.0;
138 toplevel
->property_y2() = 10.0;
139 toplevel
->property_fill() = true;
140 toplevel
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorBase
.get();
141 toplevel
->property_outline_pixels() = 0;
142 toplevel
->signal_event().connect (sigc::mem_fun (*this, &CrossfadeEditor::canvas_event
));
144 fade
[Out
].line
= new ArdourCanvas::Line (*(canvas
->root()));
145 fade
[Out
].line
->property_width_pixels() = 1;
146 fade
[Out
].line
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorLine
.get();
148 fade
[Out
].shading
= new ArdourCanvas::Polygon (*(canvas
->root()));
149 fade
[Out
].shading
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorLineShading
.get();
151 fade
[In
].line
= new ArdourCanvas::Line (*(canvas
->root()));
152 fade
[In
].line
->property_width_pixels() = 1;
153 fade
[In
].line
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorLine
.get();
155 fade
[In
].shading
= new ArdourCanvas::Polygon (*(canvas
->root()));
156 fade
[In
].shading
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorLineShading
.get();
158 fade
[In
].shading
->signal_event().connect (sigc::mem_fun (*this, &CrossfadeEditor::canvas_event
));
159 fade
[In
].line
->signal_event().connect (sigc::mem_fun (*this, &CrossfadeEditor::curve_event
));
160 fade
[Out
].shading
->signal_event().connect (sigc::mem_fun (*this, &CrossfadeEditor::canvas_event
));
161 fade
[Out
].line
->signal_event().connect (sigc::mem_fun (*this, &CrossfadeEditor::curve_event
));
163 select_in_button
.set_name (X_("CrossfadeEditCurveButton"));
164 select_out_button
.set_name (X_("CrossfadeEditCurveButton"));
166 select_in_button
.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &CrossfadeEditor::curve_select_clicked
), In
));
167 select_out_button
.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &CrossfadeEditor::curve_select_clicked
), Out
));
169 HBox
* acbox
= manage (new HBox
);
171 audition_box
.set_border_width (7);
172 audition_box
.set_spacing (5);
173 audition_box
.set_homogeneous (false);
174 audition_box
.pack_start (audition_left_dry_button
, false, false);
175 audition_box
.pack_start (audition_left_button
, false, false);
176 audition_box
.pack_start (audition_both_button
, false, false);
177 audition_box
.pack_start (audition_right_button
, false, false);
178 audition_box
.pack_start (audition_right_dry_button
, false, false);
180 Frame
* audition_frame
= manage (new Frame (_("Audition")));
182 audition_frame
->set_name (X_("CrossfadeEditFrame"));
183 audition_frame
->add (audition_box
);
185 acbox
->pack_start (*audition_frame
, true, false);
187 Frame
* canvas_frame
= manage (new Frame
);
188 canvas_frame
->add (*canvas
);
189 canvas_frame
->set_shadow_type (Gtk::SHADOW_IN
);
191 fade_in_table
.attach (select_in_button
, 0, 2, 0, 1, Gtk::FILL
|Gtk::EXPAND
);
192 fade_out_table
.attach (select_out_button
, 0, 2, 0, 1, Gtk::FILL
|Gtk::EXPAND
);
202 for (list
<Preset
*>::iterator i
= fade_in_presets
->begin(); i
!= fade_in_presets
->end(); ++i
) {
204 pxmap
= manage (new Image (::get_icon ((*i
)->image_name
)));
205 pbutton
= manage (new Button
);
206 pbutton
->add (*pxmap
);
207 pbutton
->set_name ("CrossfadeEditButton");
208 pbutton
->signal_clicked().connect (sigc::bind (sigc::mem_fun(*this, &CrossfadeEditor::apply_preset
), *i
));
209 ARDOUR_UI::instance()->set_tip (pbutton
, (*i
)->name
, "");
210 fade_in_table
.attach (*pbutton
, col
, col
+1, row
, row
+1);
211 fade_in_buttons
.push_back (pbutton
);
224 for (list
<Preset
*>::iterator i
= fade_out_presets
->begin(); i
!= fade_out_presets
->end(); ++i
) {
226 pxmap
= manage (new Image (::get_icon ((*i
)->image_name
)));
227 pbutton
= manage (new Button
);
228 pbutton
->add (*pxmap
);
229 pbutton
->set_name ("CrossfadeEditButton");
230 pbutton
->signal_clicked().connect (sigc::bind (sigc::mem_fun(*this, &CrossfadeEditor::apply_preset
), *i
));
231 ARDOUR_UI::instance()->set_tip (pbutton
, (*i
)->name
, "");
232 fade_out_table
.attach (*pbutton
, col
, col
+1, row
, row
+1);
233 fade_out_buttons
.push_back (pbutton
);
243 clear_button
.set_name ("CrossfadeEditButton");
244 revert_button
.set_name ("CrossfadeEditButton");
245 ok_button
->set_name ("CrossfadeEditButton");
246 cancel_button
->set_name ("CrossfadeEditButton");
247 preroll_button
.set_name ("CrossfadeEditButton");
248 postroll_button
.set_name ("CrossfadeEditButton");
249 audition_both_button
.set_name ("CrossfadeEditAuditionButton");
250 audition_left_dry_button
.set_name ("CrossfadeEditAuditionButton");
251 audition_left_button
.set_name ("CrossfadeEditAuditionButton");
252 audition_right_dry_button
.set_name ("CrossfadeEditAuditionButton");
253 audition_right_button
.set_name ("CrossfadeEditAuditionButton");
255 clear_button
.signal_clicked().connect (sigc::mem_fun(*this, &CrossfadeEditor::clear
));
256 revert_button
.signal_clicked().connect (sigc::mem_fun(*this, &CrossfadeEditor::reset
));
257 audition_both_button
.signal_toggled().connect (sigc::mem_fun(*this, &CrossfadeEditor::audition_toggled
));
258 audition_right_button
.signal_toggled().connect (sigc::mem_fun(*this, &CrossfadeEditor::audition_right_toggled
));
259 audition_right_dry_button
.signal_toggled().connect (sigc::mem_fun(*this, &CrossfadeEditor::audition_right_dry_toggled
));
260 audition_left_button
.signal_toggled().connect (sigc::mem_fun(*this, &CrossfadeEditor::audition_left_toggled
));
261 audition_left_dry_button
.signal_toggled().connect (sigc::mem_fun(*this, &CrossfadeEditor::audition_left_dry_toggled
));
263 roll_box
.pack_start (preroll_button
, false, false);
264 roll_box
.pack_start (postroll_button
, false, false);
266 Gtk::HBox
* rcenter_box
= manage (new HBox
);
267 rcenter_box
->pack_start (roll_box
, true, false);
269 VBox
* vpacker2
= manage (new (VBox
));
271 vpacker2
->set_border_width (12);
272 vpacker2
->set_spacing (7);
273 vpacker2
->pack_start (*acbox
, false, false);
274 vpacker2
->pack_start (*rcenter_box
, false, false);
276 curve_button_box
.set_spacing (7);
277 curve_button_box
.pack_start (fade_out_table
, false, false, 12);
278 curve_button_box
.pack_start (*vpacker2
, false, false, 12);
279 curve_button_box
.pack_start (fade_in_table
, false, false, 12);
281 get_vbox()->pack_start (*canvas_frame
, true, true);
282 get_vbox()->pack_start (curve_button_box
, false, false);
284 /* button to allow hackers to check the actual curve values */
286 // Button* foobut = manage (new Button ("dump"));
287 // foobut-.signal_clicked().connect (sigc::mem_fun(*this, &CrossfadeEditor::dump));
288 // vpacker.pack_start (*foobut, false, false);
291 set (xfade
->fade_in(), In
);
294 set (xfade
->fade_out(), Out
);
296 curve_select_clicked (In
);
298 xfade
->PropertyChanged
.connect (state_connection
, invalidator (*this), ui_bind (&CrossfadeEditor::xfade_changed
, this, _1
), gui_context());
300 _session
->AuditionActive
.connect (_session_connections
, invalidator (*this), ui_bind (&CrossfadeEditor::audition_state_changed
, this, _1
), gui_context());
304 CrossfadeEditor::~CrossfadeEditor()
306 /* most objects will be destroyed when the toplevel window is. */
308 for (list
<Point
*>::iterator i
= fade
[In
].points
.begin(); i
!= fade
[In
].points
.end(); ++i
) {
312 for (list
<Point
*>::iterator i
= fade
[Out
].points
.begin(); i
!= fade
[Out
].points
.end(); ++i
) {
316 delete _peaks_ready_connection
;
320 CrossfadeEditor::dump ()
322 for (AutomationList::iterator i
= fade
[Out
].normative_curve
.begin(); i
!= fade
[Out
].normative_curve
.end(); ++i
) {
323 cerr
<< (*i
)->when
<< ' ' << (*i
)->value
<< endl
;
328 CrossfadeEditor::audition_state_changed (bool yn
)
330 ENSURE_GUI_THREAD (*this, &CrossfadeEditor::audition_state_changed
, yn
)
333 audition_both_button
.set_active (false);
334 audition_left_button
.set_active (false);
335 audition_right_button
.set_active (false);
336 audition_left_dry_button
.set_active (false);
337 audition_right_dry_button
.set_active (false);
342 CrossfadeEditor::set (const ARDOUR::AutomationList
& curve
, WhichFade which
)
345 ARDOUR::AutomationList::const_iterator the_end
;
347 for (list
<Point
*>::iterator i
= fade
[which
].points
.begin(); i
!= fade
[which
].points
.end(); ++i
) {
351 fade
[which
].points
.clear ();
352 fade
[which
].gain_curve
.clear ();
353 fade
[which
].normative_curve
.clear ();
359 the_end
= curve
.end();
362 firstx
= (*curve
.begin())->when
;
363 endx
= (*the_end
)->when
;
365 for (ARDOUR::AutomationList::const_iterator i
= curve
.begin(); i
!= curve
.end(); ++i
) {
367 double xfract
= ((*i
)->when
- firstx
) / (endx
- firstx
);
368 double yfract
= ((*i
)->value
- miny
) / (maxy
- miny
);
370 Point
* p
= make_point ();
372 p
->move_to (x_coordinate (xfract
), y_coordinate (yfract
),
375 fade
[which
].points
.push_back (p
);
378 /* no need to sort because curve is already time-ordered */
382 swap (which
, current
);
384 swap (which
, current
);
388 CrossfadeEditor::curve_event (GdkEvent
* event
)
390 /* treat it like a toplevel event */
392 return canvas_event (event
);
396 CrossfadeEditor::point_event (GdkEvent
* event
, Point
* point
)
399 if (point
->curve
!= fade
[current
].line
) {
403 switch (event
->type
) {
404 case GDK_BUTTON_PRESS
:
405 point_grabbed
= true;
407 case GDK_BUTTON_RELEASE
:
408 point_grabbed
= false;
410 if (Keyboard::is_delete_event (&event
->button
)) {
411 fade
[current
].points
.remove (point
);
418 case GDK_MOTION_NOTIFY
:
422 /* can't drag first or last points horizontally or vertically */
424 if (point
== fade
[current
].points
.front() || point
== fade
[current
].points
.back()) {
428 new_x
= (event
->motion
.x
- canvas_border
)/effective_width();
429 new_y
= 1.0 - ((event
->motion
.y
- canvas_border
)/effective_height());
432 point
->move_to (x_coordinate (new_x
), y_coordinate (new_y
),
444 CrossfadeEditor::canvas_event (GdkEvent
* event
)
446 switch (event
->type
) {
447 case GDK_BUTTON_PRESS
:
448 add_control_point ((event
->button
.x
- canvas_border
)/effective_width(),
449 1.0 - ((event
->button
.y
- canvas_border
)/effective_height()));
458 CrossfadeEditor::Point::~Point()
463 CrossfadeEditor::Point
*
464 CrossfadeEditor::make_point ()
466 Point
* p
= new Point
;
468 p
->box
= new ArdourCanvas::SimpleRect (*(canvas
->root()));
469 p
->box
->property_fill() = true;
470 p
->box
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorPointFill
.get();
471 p
->box
->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorPointOutline
.get();
472 p
->box
->property_outline_pixels() = 1;
474 p
->curve
= fade
[current
].line
;
476 p
->box
->signal_event().connect (sigc::bind (sigc::mem_fun (*this, &CrossfadeEditor::point_event
), p
));
482 CrossfadeEditor::add_control_point (double x
, double y
)
486 /* enforce end point x location */
488 if (fade
[current
].points
.empty()) {
490 } else if (fade
[current
].points
.size() == 1) {
494 Point
* p
= make_point ();
496 p
->move_to (x_coordinate (x
), y_coordinate (y
), x
, y
);
498 fade
[current
].points
.push_back (p
);
499 fade
[current
].points
.sort (cmp
);
505 CrossfadeEditor::Point::move_to (double nx
, double ny
, double xfract
, double yfract
)
507 if ( xfract
< 0.0 ) {
509 } else if ( xfract
> 1.0 ) {
513 if ( yfract
< 0.0 ) {
515 } else if ( yfract
> 1.0 ) {
519 const double half_size
= rint(size
/2.0);
520 double x1
= nx
- half_size
;
521 double x2
= nx
+ half_size
;
523 box
->property_x1() = x1
;
524 box
->property_x2() = x2
;
526 box
->property_y1() = ny
- half_size
;
527 box
->property_y2() = ny
+ half_size
;
534 CrossfadeEditor::canvas_allocation (Gtk::Allocation
& /*alloc*/)
537 toplevel
->property_x1() = 0.0;
538 toplevel
->property_y1() = 0.0;
539 toplevel
->property_x2() = (double) canvas
->get_allocation().get_width() + canvas_border
;
540 toplevel
->property_y2() = (double) canvas
->get_allocation().get_height() + canvas_border
;
543 canvas
->set_scroll_region (0.0, 0.0,
544 canvas
->get_allocation().get_width(),
545 canvas
->get_allocation().get_height());
547 Point
* end
= make_point ();
550 if (fade
[In
].points
.size() > 1) {
551 Point
* old_end
= fade
[In
].points
.back();
552 fade
[In
].points
.pop_back ();
553 end
->move_to (x_coordinate (old_end
->x
),
554 y_coordinate (old_end
->y
),
555 old_end
->x
, old_end
->y
);
560 end
->move_to (x_coordinate (x
), y_coordinate (y
), x
, y
);
564 fade
[In
].points
.push_back (end
);
565 fade
[In
].points
.sort (cmp
);
567 for (list
<Point
*>::iterator i
= fade
[In
].points
.begin(); i
!= fade
[In
].points
.end(); ++i
) {
568 (*i
)->move_to (x_coordinate((*i
)->x
), y_coordinate((*i
)->y
),
574 if (fade
[Out
].points
.size() > 1) {
575 Point
* old_end
= fade
[Out
].points
.back();
576 fade
[Out
].points
.pop_back ();
577 end
->move_to (x_coordinate (old_end
->x
),
578 y_coordinate (old_end
->y
),
579 old_end
->x
, old_end
->y
);
584 end
->move_to (x_coordinate (x
), y_coordinate (y
), x
, y
);
588 fade
[Out
].points
.push_back (end
);
589 fade
[Out
].points
.sort (cmp
);
591 for (list
<Point
*>::iterator i
= fade
[Out
].points
.begin(); i
!= fade
[Out
].points
.end(); ++i
) {
592 (*i
)->move_to (x_coordinate ((*i
)->x
),
593 y_coordinate ((*i
)->y
),
597 WhichFade old_current
= current
;
602 current
= old_current
;
604 double spu
= xfade
->length() / (double) effective_width();
606 if (fade
[In
].waves
.empty()) {
607 make_waves (xfade
->in(), In
);
610 if (fade
[Out
].waves
.empty()) {
611 make_waves (xfade
->out(), Out
);
615 vector
<ArdourCanvas::WaveView
*>::iterator i
;
618 ht
= canvas
->get_allocation().get_height() / xfade
->in()->n_channels();
620 for (n
= 0, i
= fade
[In
].waves
.begin(); i
!= fade
[In
].waves
.end(); ++i
, ++n
) {
625 (*i
)->property_y() = yoff
;
626 (*i
)->property_height() = ht
;
627 (*i
)->property_samples_per_unit() = spu
;
630 ht
= canvas
->get_allocation().get_height() / xfade
->out()->n_channels();
632 for (n
= 0, i
= fade
[Out
].waves
.begin(); i
!= fade
[Out
].waves
.end(); ++i
, ++n
) {
637 (*i
)->property_y() = yoff
;
638 (*i
)->property_height() = ht
;
639 (*i
)->property_samples_per_unit() = spu
;
646 CrossfadeEditor::xfade_changed (const PropertyChange
&)
648 set (xfade
->fade_in(), In
);
649 set (xfade
->fade_out(), Out
);
653 CrossfadeEditor::redraw ()
655 if (canvas
->get_allocation().get_width() < 2) {
659 framecnt_t len
= xfade
->length ();
661 fade
[current
].normative_curve
.clear ();
662 fade
[current
].gain_curve
.clear ();
664 for (list
<Point
*>::iterator i
= fade
[current
].points
.begin(); i
!= fade
[current
].points
.end(); ++i
) {
665 fade
[current
].normative_curve
.add ((*i
)->x
, (*i
)->y
);
668 offset
= xfade
->in()->start();
670 offset
= xfade
->out()->start()+xfade
->out()->length()-xfade
->length();
671 fade
[current
].gain_curve
.add (((*i
)->x
* len
) + offset
, (*i
)->y
);
675 size_t npoints
= (size_t) effective_width();
678 fade
[current
].normative_curve
.curve().get_vector (0, 1.0, vec
, npoints
);
680 ArdourCanvas::Points pts
;
681 ArdourCanvas::Points spts
;
683 while (pts
.size() < npoints
) {
684 pts
.push_back (Gnome::Art::Point (0,0));
687 while (spts
.size() < npoints
+ 3) {
688 spts
.push_back (Gnome::Art::Point (0,0));
691 /* the shade coordinates *MUST* be in anti-clockwise order.
698 spts
[0].set_x (canvas_border
);
699 spts
[0].set_y (effective_height() + canvas_border
);
703 spts
[1].set_x (effective_width() + canvas_border
);
704 spts
[1].set_y (effective_height() + canvas_border
);
708 spts
[2].set_x (effective_width() + canvas_border
);
709 spts
[2].set_y (canvas_border
);
716 spts
[0].set_x (canvas_border
);
717 spts
[0].set_y (canvas_border
);
721 spts
[1].set_x (canvas_border
);
722 spts
[1].set_y (effective_height() + canvas_border
);
726 spts
[2].set_x (effective_width() + canvas_border
);
727 spts
[2].set_y (effective_height() + canvas_border
);
731 size_t last_spt
= (npoints
+ 3) - 1;
733 for (size_t i
= 0; i
< npoints
; ++i
) {
737 pts
[i
].set_x (canvas_border
+ i
);
738 pts
[i
].set_y (y_coordinate (y
));
740 spts
[last_spt
- i
].set_x (canvas_border
+ i
);
741 spts
[last_spt
- i
].set_y (pts
[i
].get_y());
744 fade
[current
].line
->property_points() = pts
;
745 fade
[current
].shading
->property_points() = spts
;
747 for (vector
<ArdourCanvas::WaveView
*>::iterator i
= fade
[current
].waves
.begin(); i
!= fade
[current
].waves
.end(); ++i
) {
748 (*i
)->property_gain_src() = static_cast<Evoral::Curve
*>(&fade
[current
].gain_curve
.curve());
753 CrossfadeEditor::apply_preset (Preset
*preset
)
756 WhichFade wf
= find(fade_in_presets
->begin(), fade_in_presets
->end(), preset
) != fade_in_presets
->end() ? In
: Out
;
761 select_in_button
.clicked();
763 select_out_button
.clicked();
766 curve_select_clicked (wf
);
769 for (list
<Point
*>::iterator i
= fade
[current
].points
.begin(); i
!= fade
[current
].points
.end(); ++i
) {
773 fade
[current
].points
.clear ();
775 for (Preset::iterator i
= preset
->begin(); i
!= preset
->end(); ++i
) {
776 Point
* p
= make_point ();
777 p
->move_to (x_coordinate ((*i
).x
), y_coordinate ((*i
).y
),
779 fade
[current
].points
.push_back (p
);
786 CrossfadeEditor::apply ()
788 _session
->begin_reversible_command (_("Edit crossfade"));
790 XMLNode
& before
= xfade
->get_state ();
794 _session
->add_command (new MementoCommand
<Crossfade
> (*xfade
.get(), &before
, &xfade
->get_state ()));
795 _session
->commit_reversible_command ();
799 CrossfadeEditor::_apply_to (boost::shared_ptr
<Crossfade
> xf
)
801 ARDOUR::AutomationList
& in (xf
->fade_in());
802 ARDOUR::AutomationList
& out (xf
->fade_out());
807 ARDOUR::AutomationList::const_iterator the_end
= in
.end();
810 double firstx
= (*in
.begin())->when
;
811 double endx
= (*the_end
)->when
;
816 for (list
<Point
*>::iterator i
= fade
[In
].points
.begin(); i
!= fade
[In
].points
.end(); ++i
) {
818 double when
= firstx
+ ((*i
)->x
* (endx
- firstx
));
819 double value
= (*i
)->y
;
820 in
.add (when
, value
);
828 firstx
= (*out
.begin())->when
;
829 endx
= (*the_end
)->when
;
834 for (list
<Point
*>::iterator i
= fade
[Out
].points
.begin(); i
!= fade
[Out
].points
.end(); ++i
) {
836 double when
= firstx
+ ((*i
)->x
* (endx
- firstx
));
837 double value
= (*i
)->y
;
838 out
.add (when
, value
);
846 CrossfadeEditor::setup (boost::shared_ptr
<Crossfade
> xfade
)
849 xfade
->set_active (true);
850 xfade
->fade_in().curve().solve ();
851 xfade
->fade_out().curve().solve ();
855 CrossfadeEditor::clear ()
857 for (list
<Point
*>::iterator i
= fade
[current
].points
.begin(); i
!= fade
[current
].points
.end(); ++i
) {
861 fade
[current
].points
.clear ();
867 CrossfadeEditor::reset ()
869 set (xfade
->fade_in(), In
);
870 set (xfade
->fade_out(), Out
);
872 curve_select_clicked (current
);
876 CrossfadeEditor::build_presets ()
880 fade_in_presets
= new Presets
;
881 fade_out_presets
= new Presets
;
885 p
= new Preset ("Linear (-6dB)", "crossfade-in-linear");
886 p
->push_back (PresetPoint (0, 0));
887 p
->push_back (PresetPoint (0.000000, 0.000000));
888 p
->push_back (PresetPoint (0.166667, 0.166366));
889 p
->push_back (PresetPoint (0.333333, 0.332853));
890 p
->push_back (PresetPoint (0.500000, 0.499459));
891 p
->push_back (PresetPoint (0.666667, 0.666186));
892 p
->push_back (PresetPoint (0.833333, 0.833033));
893 p
->push_back (PresetPoint (1.000000, 1.000000));
894 fade_in_presets
->push_back (p
);
896 p
= new Preset ("S(1)-curve", "crossfade-in-S1");
897 p
->push_back (PresetPoint (0, 0));
898 p
->push_back (PresetPoint (0.1, 0.01));
899 p
->push_back (PresetPoint (0.2, 0.03));
900 p
->push_back (PresetPoint (0.8, 0.97));
901 p
->push_back (PresetPoint (0.9, 0.99));
902 p
->push_back (PresetPoint (1, 1));
903 fade_in_presets
->push_back (p
);
905 p
= new Preset ("S(2)-curve", "crossfade-in-S2");
906 p
->push_back (PresetPoint (0.0, 0.0));
907 p
->push_back (PresetPoint (0.055, 0.222));
908 p
->push_back (PresetPoint (0.163, 0.35));
909 p
->push_back (PresetPoint (0.837, 0.678));
910 p
->push_back (PresetPoint (0.945, 0.783));
911 p
->push_back (PresetPoint (1.0, 1.0));
912 fade_in_presets
->push_back (p
);
914 p
= new Preset ("Constant Power (-3dB)", "crossfade-in-constant-power");
916 p
->push_back (PresetPoint (0.000000, 0.000000));
917 p
->push_back (PresetPoint (0.166667, 0.282192));
918 p
->push_back (PresetPoint (0.333333, 0.518174));
919 p
->push_back (PresetPoint (0.500000, 0.707946));
920 p
->push_back (PresetPoint (0.666667, 0.851507));
921 p
->push_back (PresetPoint (0.833333, 0.948859));
922 p
->push_back (PresetPoint (1.000000, 1.000000));
924 fade_in_presets
->push_back (p
);
926 if (!Profile
->get_sae()) {
928 p
= new Preset ("Short cut", "crossfade-in-short-cut");
929 p
->push_back (PresetPoint (0, 0));
930 p
->push_back (PresetPoint (0.389401, 0.0333333));
931 p
->push_back (PresetPoint (0.629032, 0.0861111));
932 p
->push_back (PresetPoint (0.829493, 0.233333));
933 p
->push_back (PresetPoint (0.9447, 0.483333));
934 p
->push_back (PresetPoint (0.976959, 0.697222));
935 p
->push_back (PresetPoint (1, 1));
936 fade_in_presets
->push_back (p
);
938 p
= new Preset ("Slow cut", "crossfade-in-slow-cut");
939 p
->push_back (PresetPoint (0, 0));
940 p
->push_back (PresetPoint (0.304147, 0.0694444));
941 p
->push_back (PresetPoint (0.529954, 0.152778));
942 p
->push_back (PresetPoint (0.725806, 0.333333));
943 p
->push_back (PresetPoint (0.847926, 0.558333));
944 p
->push_back (PresetPoint (0.919355, 0.730556));
945 p
->push_back (PresetPoint (1, 1));
946 fade_in_presets
->push_back (p
);
948 p
= new Preset ("Fast cut", "crossfade-in-fast-cut");
949 p
->push_back (PresetPoint (0, 0));
950 p
->push_back (PresetPoint (0.0737327, 0.308333));
951 p
->push_back (PresetPoint (0.246544, 0.658333));
952 p
->push_back (PresetPoint (0.470046, 0.886111));
953 p
->push_back (PresetPoint (0.652074, 0.972222));
954 p
->push_back (PresetPoint (0.771889, 0.988889));
955 p
->push_back (PresetPoint (1, 1));
956 fade_in_presets
->push_back (p
);
958 p
= new Preset ("Long cut", "crossfade-in-long-cut");
959 p
->push_back (PresetPoint (0, 0));
960 p
->push_back (PresetPoint (0.0207373, 0.197222));
961 p
->push_back (PresetPoint (0.0645161, 0.525));
962 p
->push_back (PresetPoint (0.152074, 0.802778));
963 p
->push_back (PresetPoint (0.276498, 0.919444));
964 p
->push_back (PresetPoint (0.481567, 0.980556));
965 p
->push_back (PresetPoint (0.767281, 1));
966 p
->push_back (PresetPoint (1, 1));
967 fade_in_presets
->push_back (p
);
972 // p = new Preset ("regout.xpm");
973 p
= new Preset ("Linear (-6dB cut)", "crossfade-out-linear");
974 p
->push_back (PresetPoint (0, 1));
975 p
->push_back (PresetPoint (0.000000, 1.000000));
976 p
->push_back (PresetPoint (0.166667, 0.833033));
977 p
->push_back (PresetPoint (0.333333, 0.666186));
978 p
->push_back (PresetPoint (0.500000, 0.499459));
979 p
->push_back (PresetPoint (0.666667, 0.332853));
980 p
->push_back (PresetPoint (0.833333, 0.166366));
981 p
->push_back (PresetPoint (1.000000, 0.000000));
982 fade_out_presets
->push_back (p
);
984 p
= new Preset ("S(1)-Curve", "crossfade-out-S1");
985 p
->push_back (PresetPoint (0, 1));
986 p
->push_back (PresetPoint (0.1, 0.99));
987 p
->push_back (PresetPoint (0.2, 0.97));
988 p
->push_back (PresetPoint (0.8, 0.03));
989 p
->push_back (PresetPoint (0.9, 0.01));
990 p
->push_back (PresetPoint (1, 0));
991 fade_out_presets
->push_back (p
);
993 p
= new Preset ("S(2)-Curve", "crossfade-out-S2");
994 p
->push_back (PresetPoint (0.0, 1.0));
995 p
->push_back (PresetPoint (0.163, 0.678));
996 p
->push_back (PresetPoint (0.055, 0.783));
997 p
->push_back (PresetPoint (0.837, 0.35));
998 p
->push_back (PresetPoint (0.945, 0.222));
999 p
->push_back (PresetPoint (1.0, 0.0));
1000 fade_out_presets
->push_back (p
);
1002 // p = new Preset ("linout.xpm");
1003 p
= new Preset ("Constant Power (-3dB cut)", "crossfade-out-constant-power");
1004 p
->push_back (PresetPoint (0.000000, 1.000000));
1005 p
->push_back (PresetPoint (0.166667, 0.948859));
1006 p
->push_back (PresetPoint (0.333333, 0.851507));
1007 p
->push_back (PresetPoint (0.500000, 0.707946));
1008 p
->push_back (PresetPoint (0.666667, 0.518174));
1009 p
->push_back (PresetPoint (0.833333, 0.282192));
1010 p
->push_back (PresetPoint (1.000000, 0.000000));
1011 fade_out_presets
->push_back (p
);
1013 if (!Profile
->get_sae()) {
1014 // p = new Preset ("hiout.xpm");
1015 p
= new Preset ("Short cut", "crossfade-out-short-cut");
1016 p
->push_back (PresetPoint (0, 1));
1017 p
->push_back (PresetPoint (0.305556, 1));
1018 p
->push_back (PresetPoint (0.548611, 0.991736));
1019 p
->push_back (PresetPoint (0.759259, 0.931129));
1020 p
->push_back (PresetPoint (0.918981, 0.68595));
1021 p
->push_back (PresetPoint (0.976852, 0.22865));
1022 p
->push_back (PresetPoint (1, 0));
1023 fade_out_presets
->push_back (p
);
1025 p
= new Preset ("Slow cut", "crossfade-out-slow-cut");
1026 p
->push_back (PresetPoint (0, 1));
1027 p
->push_back (PresetPoint (0.228111, 0.988889));
1028 p
->push_back (PresetPoint (0.347926, 0.972222));
1029 p
->push_back (PresetPoint (0.529954, 0.886111));
1030 p
->push_back (PresetPoint (0.753456, 0.658333));
1031 p
->push_back (PresetPoint (0.9262673, 0.308333));
1032 p
->push_back (PresetPoint (1, 0));
1033 fade_out_presets
->push_back (p
);
1035 p
= new Preset ("Fast cut", "crossfade-out-fast-cut");
1036 p
->push_back (PresetPoint (0, 1));
1037 p
->push_back (PresetPoint (0.080645, 0.730556));
1038 p
->push_back (PresetPoint (0.277778, 0.289256));
1039 p
->push_back (PresetPoint (0.470046, 0.152778));
1040 p
->push_back (PresetPoint (0.695853, 0.0694444));
1041 p
->push_back (PresetPoint (1, 0));
1042 fade_out_presets
->push_back (p
);
1044 // p = new Preset ("loout.xpm");
1045 p
= new Preset ("Long cut", "crossfade-out-long-cut");
1046 p
->push_back (PresetPoint (0, 1));
1047 p
->push_back (PresetPoint (0.023041, 0.697222));
1048 p
->push_back (PresetPoint (0.0553, 0.483333));
1049 p
->push_back (PresetPoint (0.170507, 0.233333));
1050 p
->push_back (PresetPoint (0.370968, 0.0861111));
1051 p
->push_back (PresetPoint (0.610599, 0.0333333));
1052 p
->push_back (PresetPoint (1, 0));
1053 fade_out_presets
->push_back (p
);
1059 CrossfadeEditor::curve_select_clicked (WhichFade wf
)
1065 for (vector
<ArdourCanvas::WaveView
*>::iterator i
= fade
[In
].waves
.begin(); i
!= fade
[In
].waves
.end(); ++i
) {
1066 (*i
)->property_wave_color() = ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorWave
.get();
1067 (*i
)->property_fill_color() = ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorWave
.get();
1070 for (vector
<ArdourCanvas::WaveView
*>::iterator i
= fade
[Out
].waves
.begin(); i
!= fade
[Out
].waves
.end(); ++i
) {
1071 (*i
)->property_wave_color() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorWave
.get();
1072 (*i
)->property_fill_color() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorWave
.get();
1075 fade
[In
].line
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorLine
.get();
1076 fade
[Out
].line
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorLine
.get();
1077 fade
[Out
].shading
->hide();
1078 fade
[In
].shading
->show();
1080 for (list
<Point
*>::iterator i
= fade
[Out
].points
.begin(); i
!= fade
[Out
].points
.end(); ++i
) {
1084 for (list
<Point
*>::iterator i
= fade
[In
].points
.begin(); i
!= fade
[In
].points
.end(); ++i
) {
1090 for (vector
<ArdourCanvas::WaveView
*>::iterator i
= fade
[In
].waves
.begin(); i
!= fade
[In
].waves
.end(); ++i
) {
1091 (*i
)->property_wave_color() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorWave
.get();
1092 (*i
)->property_fill_color() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorWave
.get();
1095 for (vector
<ArdourCanvas::WaveView
*>::iterator i
= fade
[Out
].waves
.begin(); i
!= fade
[Out
].waves
.end(); ++i
) {
1096 (*i
)->property_wave_color() = ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorWave
.get();
1097 (*i
)->property_fill_color() = ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorWave
.get();
1100 fade
[Out
].line
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorLine
.get();
1101 fade
[In
].line
->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeEditorLine
.get();
1102 fade
[In
].shading
->hide();
1103 fade
[Out
].shading
->show();
1105 for (list
<Point
*>::iterator i
= fade
[In
].points
.begin(); i
!= fade
[In
].points
.end(); ++i
) {
1109 for (list
<Point
*>::iterator i
= fade
[Out
].points
.begin(); i
!= fade
[Out
].points
.end(); ++i
) {
1117 CrossfadeEditor::x_coordinate (double& xfract
) const
1119 xfract
= min (1.0, xfract
);
1120 xfract
= max (0.0, xfract
);
1122 return canvas_border
+ (xfract
* effective_width());
1126 CrossfadeEditor::y_coordinate (double& yfract
) const
1128 yfract
= min (1.0, yfract
);
1129 yfract
= max (0.0, yfract
);
1131 return (canvas
->get_allocation().get_height() - (canvas_border
)) - (yfract
* effective_height());
1135 CrossfadeEditor::make_waves (boost::shared_ptr
<AudioRegion
> region
, WhichFade which
)
1138 uint32_t nchans
= region
->n_channels();
1143 color
= ARDOUR_UI::config()->canvasvar_SelectedCrossfadeEditorWave
.get();
1145 color
= ARDOUR_UI::config()->canvasvar_CrossfadeEditorWave
.get();
1148 ht
= canvas
->get_allocation().get_height() / (double) nchans
;
1149 spu
= xfade
->length() / (double) effective_width();
1151 delete _peaks_ready_connection
;
1152 _peaks_ready_connection
= 0;
1154 for (uint32_t n
= 0; n
< nchans
; ++n
) {
1156 gdouble yoff
= n
* ht
;
1158 if (region
->audio_source(n
)->peaks_ready (boost::bind (&CrossfadeEditor::peaks_ready
, this, boost::weak_ptr
<AudioRegion
>(region
), which
), &_peaks_ready_connection
, gui_context())) {
1159 WaveView
* waveview
= new WaveView (*(canvas
->root()));
1161 waveview
->property_data_src() = region
.get();
1162 waveview
->property_cache_updater() = true;
1163 waveview
->property_cache() = WaveView::create_cache();
1164 waveview
->property_channel() = n
;
1165 waveview
->property_length_function() = (void*) region_length_from_c
;
1166 waveview
->property_sourcefile_length_function() = (void*) sourcefile_length_from_c
;
1167 waveview
->property_peak_function() = (void*) region_read_peaks_from_c
;
1168 waveview
->property_gain_function() = (void*) curve_get_vector_from_c
;
1169 waveview
->property_gain_src() = static_cast<Evoral::Curve
*>(&fade
[which
].gain_curve
.curve());
1170 waveview
->property_x() = canvas_border
;
1171 waveview
->property_y() = yoff
;
1172 waveview
->property_height() = ht
;
1173 waveview
->property_samples_per_unit() = spu
;
1174 waveview
->property_amplitude_above_axis() = 2.0;
1175 waveview
->property_wave_color() = color
;
1176 waveview
->property_fill_color() = color
;
1179 waveview
->property_region_start() = region
->start();
1181 waveview
->property_region_start() = region
->start()+region
->length()-xfade
->length();
1183 waveview
->lower_to_bottom();
1184 fade
[which
].waves
.push_back (waveview
);
1188 toplevel
->lower_to_bottom();
1192 CrossfadeEditor::peaks_ready (boost::weak_ptr
<AudioRegion
> wr
, WhichFade which
)
1194 boost::shared_ptr
<AudioRegion
> r (wr
.lock());
1200 /* this should never be called, because the peak files for an xfade
1201 will be ready by the time we want them. but our API forces us
1202 to provide this, so ..
1204 delete _peaks_ready_connection
;
1205 _peaks_ready_connection
= 0;
1207 make_waves (r
, which
);
1211 CrossfadeEditor::audition (Audition which
)
1213 AudioPlaylist
& pl (_session
->the_auditioner()->prepare_playlist());
1215 framecnt_t postroll
;
1216 framecnt_t left_start_offset
;
1217 framecnt_t right_length
;
1218 framecnt_t left_length
;
1220 if (which
!= Right
&& preroll_button
.get_active()) {
1221 preroll
= _session
->frame_rate() * 2; //2 second hardcoded preroll for now
1226 if (which
!= Left
&& postroll_button
.get_active()) {
1227 postroll
= _session
->frame_rate() * 2; //2 second hardcoded postroll for now
1232 // Is there enough data for the whole preroll?
1233 left_length
= xfade
->length();
1234 if ((left_start_offset
= xfade
->out()->length() - xfade
->length()) > preroll
) {
1235 left_start_offset
-= preroll
;
1237 preroll
= left_start_offset
;
1238 left_start_offset
= 0;
1240 left_length
+= preroll
;
1242 // Is there enough data for the whole postroll?
1243 right_length
= xfade
->length();
1244 if ((xfade
->in()->length() - right_length
) > postroll
) {
1245 right_length
+= postroll
;
1247 right_length
= xfade
->in()->length();
1250 PropertyList left_plist
;
1251 PropertyList right_plist
;
1254 left_plist
.add (ARDOUR::Properties::start
, left_start_offset
);
1255 left_plist
.add (ARDOUR::Properties::length
, left_length
);
1256 left_plist
.add (ARDOUR::Properties::name
, string ("xfade out"));
1257 left_plist
.add (ARDOUR::Properties::layer
, 0);
1258 left_plist
.add (ARDOUR::Properties::fade_in_active
, true);
1260 right_plist
.add (ARDOUR::Properties::start
, 0);
1261 right_plist
.add (ARDOUR::Properties::length
, right_length
);
1262 right_plist
.add (ARDOUR::Properties::name
, string("xfade in"));
1263 right_plist
.add (ARDOUR::Properties::layer
, 0);
1264 right_plist
.add (ARDOUR::Properties::fade_out_active
, true);
1266 if (which
== Left
) {
1267 right_plist
.add (ARDOUR::Properties::scale_amplitude
, 0.0f
);
1268 } else if (which
== Right
) {
1269 left_plist
.add (ARDOUR::Properties::scale_amplitude
, 0.0f
);
1272 boost::shared_ptr
<AudioRegion
> left (boost::dynamic_pointer_cast
<AudioRegion
>
1273 (RegionFactory::create (xfade
->out(), left_plist
, false)));
1274 boost::shared_ptr
<AudioRegion
> right (boost::dynamic_pointer_cast
<AudioRegion
>
1275 (RegionFactory::create (xfade
->in(), right_plist
, false)));
1277 // apply a 20ms declicking fade at the start and end of auditioning
1278 // XXX this should really be a property
1280 left
->set_fade_in_length (_session
->frame_rate() / 50);
1281 right
->set_fade_out_length (_session
->frame_rate() / 50);
1283 pl
.add_region (left
, 0);
1284 pl
.add_region (right
, 1 + preroll
);
1286 /* there is only one ... */
1287 pl
.foreach_crossfade (sigc::mem_fun (*this, &CrossfadeEditor::setup
));
1289 _session
->audition_playlist ();
1293 CrossfadeEditor::audition_both ()
1299 CrossfadeEditor::audition_left_dry ()
1303 plist
.add (ARDOUR::Properties::start
, xfade
->out()->length() - xfade
->length());
1304 plist
.add (ARDOUR::Properties::length
, xfade
->length());
1305 plist
.add (ARDOUR::Properties::name
, string("xfade left"));
1306 plist
.add (ARDOUR::Properties::layer
, 0);
1308 boost::shared_ptr
<AudioRegion
> left (boost::dynamic_pointer_cast
<AudioRegion
>
1309 (RegionFactory::create (xfade
->out(), plist
, false)));
1311 _session
->audition_region (left
);
1315 CrossfadeEditor::audition_left ()
1321 CrossfadeEditor::audition_right_dry ()
1325 plist
.add (ARDOUR::Properties::start
, 0);
1326 plist
.add (ARDOUR::Properties::length
, xfade
->length());
1327 plist
.add (ARDOUR::Properties::name
, string ("xfade right"));
1328 plist
.add (ARDOUR::Properties::layer
, 0);
1330 boost::shared_ptr
<AudioRegion
> right (boost::dynamic_pointer_cast
<AudioRegion
>
1331 (RegionFactory::create (xfade
->in(), plist
, false)));
1333 _session
->audition_region (right
);
1337 CrossfadeEditor::audition_right ()
1343 CrossfadeEditor::cancel_audition ()
1345 _session
->cancel_audition ();
1349 CrossfadeEditor::audition_toggled ()
1353 if ((x
= audition_both_button
.get_active ()) != _session
->is_auditioning()) {
1364 CrossfadeEditor::audition_right_toggled ()
1368 if ((x
= audition_right_button
.get_active ()) != _session
->is_auditioning()) {
1379 CrossfadeEditor::audition_right_dry_toggled ()
1383 if ((x
= audition_right_dry_button
.get_active ()) != _session
->is_auditioning()) {
1386 audition_right_dry ();
1394 CrossfadeEditor::audition_left_toggled ()
1398 if ((x
= audition_left_button
.get_active ()) != _session
->is_auditioning()) {
1409 CrossfadeEditor::audition_left_dry_toggled ()
1413 if ((x
= audition_left_dry_button
.get_active ()) != _session
->is_auditioning()) {
1416 audition_left_dry ();
1424 CrossfadeEditor::on_key_press_event (GdkEventKey */
*ev*/
)
1430 CrossfadeEditor::on_key_release_event (GdkEventKey
* ev
)
1432 switch (ev
->keyval
) {
1434 if (Keyboard::modifier_state_equals (ev
->state
, Keyboard::PrimaryModifier
)) {
1435 audition_right_dry_button
.set_active (!audition_right_dry_button
.get_active());
1437 audition_right_button
.set_active (!audition_right_button
.get_active());
1442 if (Keyboard::modifier_state_equals (ev
->state
, Keyboard::PrimaryModifier
)) {
1443 audition_left_dry_button
.set_active (!audition_left_dry_button
.get_active());
1445 audition_left_button
.set_active (!audition_left_button
.get_active());
1450 if (_session
->is_auditioning()) {
1453 audition_both_button
.set_active (!audition_both_button
.get_active());