22 #include <sigc++/bind.h>
24 #include <gtkmm/frame.h>
25 #include <gtkmm/image.h>
26 #include <gtkmm/scrolledwindow.h>
32 #include "ardour/crossfade.h"
40 #include "ardour/crossfade_binder.h"
44 #include "canvas/rectangle.h"
45 #include "canvas/wave_view.h"
46 #include "canvas/line.h"
47 #include "canvas/polygon.h"
106 set_wmclass (
X_(
"ardour_automationedit"), PROGRAM_NAME);
107 set_name (
"CrossfadeEditWindow");
111 add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
118 get_action_area()->set_layout(BUTTONBOX_SPREAD);
122 ok_button = add_button (
"OK", RESPONSE_ACCEPT);
131 canvas =
new ArdourCanvas::GtkCanvas ();
133 canvas->set_size_request (425, 200);
136 toplevel->set (ArdourCanvas::Rect (0, 0, 10, 10));
165 HBox* acbox = manage (
new HBox);
176 Frame* audition_frame = manage (
new Frame (
_(
"Audition")));
178 audition_frame->set_name (
X_(
"CrossfadeEditFrame"));
181 acbox->pack_start (*audition_frame,
true,
false);
183 Frame* canvas_frame = manage (
new Frame);
184 canvas_frame->add (*
canvas);
185 canvas_frame->set_shadow_type (Gtk::SHADOW_IN);
200 pxmap = manage (
new Image (::
get_icon ((*i)->image_name)));
201 pbutton = manage (
new Button);
202 pbutton->add (*pxmap);
203 pbutton->set_name (
"CrossfadeEditButton");
222 pxmap = manage (
new Image (::
get_icon ((*i)->image_name)));
223 pbutton = manage (
new Button);
224 pbutton->add (*pxmap);
225 pbutton->set_name (
"CrossfadeEditButton");
241 ok_button->set_name (
"CrossfadeEditButton");
262 Gtk::HBox* rcenter_box = manage (
new HBox);
263 rcenter_box->pack_start (
roll_box,
true,
false);
265 VBox*
vpacker2 = manage (
new (VBox));
267 vpacker2->set_border_width (12);
268 vpacker2->set_spacing (7);
269 vpacker2->pack_start (*acbox,
false,
false);
270 vpacker2->pack_start (*rcenter_box,
false,
false);
277 get_vbox()->pack_start (*canvas_frame,
true,
true);
304 for (list<Point*>::iterator i =
fade[
In].points.begin(); i !=
fade[
In].
points.end(); ++i) {
319 cerr << (*i)->when <<
' ' << (*i)->value << endl;
343 for (list<Point*>::iterator i =
fade[which].points.begin(); i !=
fade[which].
points.end(); ++i) {
355 the_end = curve.
end();
358 firstx = (*curve.
begin())->when;
359 endx = (*the_end)->when;
363 double xfract = ((*i)->when - firstx) / (endx - firstx);
399 switch (event->type) {
400 case GDK_BUTTON_PRESS:
403 case GDK_BUTTON_RELEASE:
406 if (Keyboard::is_delete_event (&event->button)) {
414 case GDK_MOTION_NOTIFY:
442 switch (event->type) {
443 case GDK_BUTTON_PRESS:
464 p->
box =
new ArdourCanvas::Rectangle (
canvas->root());
465 p->
box->set_fill (
true);
502 if ( xfract < 0.0 ) {
504 }
else if ( xfract > 1.0 ) {
508 if ( yfract < 0.0 ) {
510 }
else if ( yfract > 1.0 ) {
514 const double half_size = rint(size/2.0);
515 double x1 = nx - half_size;
516 double x2 = nx + half_size;
518 box->set (ArdourCanvas::Rect (x1, ny - half_size, x2, ny + half_size));
546 if (
fade[
In].points.size() > 1) {
551 old_end->
x, old_end->
y);
563 for (list<Point*>::iterator i =
fade[
In].points.begin(); i !=
fade[
In].
points.end(); ++i) {
570 if (
fade[
Out].points.size() > 1) {
575 old_end->
x, old_end->
y);
602 if (
fade[
In].waves.empty()) {
611 vector<ArdourCanvas::WaveView*>::iterator i;
614 ht =
canvas->get_allocation().get_height() /
xfade->in()->n_channels();
621 (*i)->set_y_position (yoff);
622 (*i)->set_height (ht);
623 (*i)->set_samples_per_pixel (spu);
626 ht =
canvas->get_allocation().get_height() /
xfade->out()->n_channels();
633 (*i)->set_y_position (yoff);
634 (*i)->set_height (ht);
635 (*i)->set_samples_per_pixel (spu);
651 if (
canvas->get_allocation().get_width() < 2) {
664 offset =
xfade->in()->start();
676 ArdourCanvas::Points pts;
677 ArdourCanvas::Points spts;
679 while (pts.size() < npoints) {
680 pts.push_back (ArdourCanvas::Duple (0,0));
683 while (spts.size() < npoints + 3) {
684 spts.push_back (ArdourCanvas::Duple (0,0));
727 size_t last_spt = (npoints + 3) - 1;
729 for (
size_t i = 0; i < npoints; ++i) {
737 spts[last_spt - i].y = pts[i].y;
771 for (Preset::iterator i = preset->begin(); i != preset->end(); ++i) {
784 the_editor().begin_reversible_command (
_(
"Edit crossfade"));
793 &before, &
xfade->get_state ()
797 the_editor().commit_reversible_command ();
812 double firstx = (*in.begin())->when;
813 double endx = (*the_end)->when;
818 for (list<Point*>::iterator i =
fade[
In].points.begin(); i !=
fade[
In].
points.end(); ++i) {
820 double when = firstx + ((*i)->x * (endx - firstx));
821 double value = (*i)->y;
822 in.add (when, value);
830 firstx = (*out.begin())->when;
831 endx = (*the_end)->when;
838 double when = firstx + ((*i)->x * (endx - firstx));
839 double value = (*i)->y;
840 out.add (when, value);
851 xfade->set_active (
true);
852 xfade->fade_in().curve().solve ();
853 xfade->fade_out().curve().solve ();
887 p =
new Preset (
"Linear (-6dB)",
"fadein-linear");
897 p =
new Preset (
"S(1)-curve",
"fadein-S1");
906 p =
new Preset (
"S(2)-curve",
"fadein-S2");
915 p =
new Preset (
"Constant power (-3dB)",
"fadein-constant-power");
929 p =
new Preset (
"Short cut",
"fadein-short-cut");
939 p =
new Preset (
"Slow cut",
"fadein-slow-cut");
949 p =
new Preset (
"Fast cut",
"fadein-fast-cut");
959 p =
new Preset (
"Long cut",
"fadein-long-cut");
974 p =
new Preset (
"Linear (-6dB cut)",
"fadeout-linear");
984 p =
new Preset (
"S(1)-Curve",
"fadeout-S1");
993 p =
new Preset (
"S(2)-Curve",
"fadeout-S2");
1003 p =
new Preset (
"Constant power (-3dB cut)",
"fadeout-constant-power");
1015 p =
new Preset (
"Short cut",
"fadeout-short-cut");
1025 p =
new Preset (
"Slow cut",
"fadeout-slow-cut");
1035 p =
new Preset (
"Fast cut",
"fadeout-fast-cut");
1045 p =
new Preset (
"Long cut",
"fadeout-long-cut");
1065 for (vector<ArdourCanvas::WaveView*>::iterator i =
fade[
In].waves.begin(); i !=
fade[
In].
waves.end(); ++i) {
1066 (*i)->set_outline_color (
ARDOUR_UI::config()->get_SelectedCrossfadeEditorWave());
1070 for (vector<ArdourCanvas::WaveView*>::iterator i =
fade[
Out].waves.begin(); i !=
fade[
Out].
waves.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) {
1095 for (vector<ArdourCanvas::WaveView*>::iterator i =
fade[
Out].waves.begin(); i !=
fade[
Out].
waves.end(); ++i) {
1096 (*i)->set_outline_color (
ARDOUR_UI::config()->get_SelectedCrossfadeEditorWave());
1105 for (list<Point*>::iterator i =
fade[
In].points.begin(); i !=
fade[
In].
points.end(); ++i) {
1119 xfract = min (1.0, xfract);
1120 xfract = max (0.0, xfract);
1128 yfract = min (1.0, yfract);
1129 yfract = max (0.0, yfract);
1148 ht =
canvas->get_allocation().get_height() / (double) nchans;
1154 for (uint32_t n = 0; n < nchans; ++n) {
1156 gdouble yoff = n * ht;
1159 ArdourCanvas::WaveView* waveview =
new ArdourCanvas::WaveView (
canvas->root(), region);
1161 waveview->set_channel (n);
1165 waveview->set_y_position (yoff);
1166 waveview->set_height (ht);
1167 waveview->set_samples_per_pixel (spu);
1168 waveview->property_amplitude_above_axis() = 2.0;
1169 waveview->set_outline_color (color);
1170 waveview->set_fill_color (color);
1173 waveview->set_region_start (region->
start() + region->
length() -
xfade->length());
1176 waveview->lower_to_bottom();
1226 left_length =
xfade->length();
1227 if ((left_start_offset =
xfade->out()->length() -
xfade->length()) > preroll) {
1228 left_start_offset -= preroll;
1230 preroll = left_start_offset;
1231 left_start_offset = 0;
1233 left_length += preroll;
1236 right_length =
xfade->length();
1237 if ((
xfade->in()->length() - right_length) > postroll) {
1238 right_length += postroll;
1240 right_length =
xfade->in()->length();
1259 if (which ==
Left) {
1261 }
else if (which ==
Right) {
1266 (RegionFactory::create (
xfade->out(), left_plist,
false)));
1268 (RegionFactory::create (
xfade->in(), right_plist,
false)));
1276 pl.add_region (left, 0);
1277 pl.add_region (right, 1 + preroll);
1302 (RegionFactory::create (
xfade->out(), plist,
false)));
1324 (RegionFactory::create (
xfade->in(), plist,
false)));
1425 switch (ev->keyval) {
1427 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1435 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
Gtk::ToggleButton audition_left_button
LIBEVORAL_API void curve_get_vector_from_c(void *arg, double, double, float *, int32_t)
LIBARDOUR_API PBD::PropertyDescriptor< bool > fade_out_active
bool on_key_release_event(GdkEventKey *)
void _apply_to(boost::shared_ptr< ARDOUR::Crossfade > xf)
std::list< Point * > points
void audition_right_dry()
double y_coordinate(double &yfract) const
double effective_height() const
double effective_width() const
void xfade_changed(const PBD::PropertyChange &)
void move_to(double x, double y, double xfract, double yfract)
LIBARDOUR_API PBD::PropertyDescriptor< layer_t > layer
static Presets * fade_in_presets
Gtk::ToggleButton audition_right_dry_button
ArdourCanvas::Rectangle * box
void audition_left_dry_toggled()
static ARDOUR_UI * instance()
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
CrossfadeEditor(ARDOUR::Session *, boost::shared_ptr< ARDOUR::Crossfade >, double miny, double maxy)
std::list< Preset * > Presets
bool curve_event(GdkEvent *event)
void add_command(Command *const cmd)
Gtk::Button * cancel_button
void audition_left_toggled()
Gtk::RadioButton select_in_button
bool is_auditioning() const
Gtk::ToggleButton audition_left_dry_button
Gtk::ToggleButton audition_both_button
static const double canvas_border
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
framecnt_t frame_rate() const
#define ENSURE_GUI_THREAD(obj, method,...)
Gtk::Button revert_button
void get_vector(double x0, double x1, float *arg, int32_t veclen)
ARDOUR::AutomationList gain_curve
boost::shared_ptr< Auditioner > the_auditioner()
std::vector< ArdourCanvas::WaveView * > waves
double x_coordinate(double &xfract) const
bool on_key_press_event(GdkEventKey *)
bool canvas_event(GdkEvent *event)
ArdourCanvas::GtkCanvas * canvas
void apply_preset(Preset *)
Gtk::ToggleButton preroll_button
LIBGTKMM2EXT_API uint64_t Keyboard
Gtk::Table fade_out_table
ArdourCanvas::Rectangle * toplevel
Gtk::RadioButton select_out_button
void peaks_ready(boost::weak_ptr< ARDOUR::AudioRegion > r, WhichFade)
Gtk::HBox curve_button_box
void set(const ARDOUR::AutomationList &alist, WhichFade)
std::vector< Gtk::Button * > fade_in_buttons
PBD::ScopedConnection state_connection
ArdourCanvas::Polygon * shading
void add_control_point(double x, double y)
boost::shared_ptr< AudioSource > audio_source(uint32_t n=0) const
void set_fade_in_length(framecnt_t)
PBD::Signal1< void, bool > AuditionActive
void swap(shared_ptr< T > &a, shared_ptr< T > &b)
void curve_select_clicked(WhichFade)
PBD::ScopedConnectionList _session_connections
void make_waves(boost::shared_ptr< ARDOUR::AudioRegion >, WhichFade)
LIBARDOUR_API RuntimeProfile * Profile
void set_tip(Gtk::Widget &w, const gchar *tip)
LIBGTKMM2EXT_API Glib::RefPtr< Gtk::UIManager > ui_manager
PBD::ScopedConnection * _peaks_ready_connection
void audition_region(boost::shared_ptr< Region >)
uint32_t n_channels() const
static const int32_t size
ARDOUR::AutomationList normative_curve
static UIConfiguration * config()
void audition_state_changed(bool)
void setup(boost::shared_ptr< ARDOUR::Crossfade >)
boost::shared_ptr< ARDOUR::Crossfade > xfade
void audition_right_dry_toggled()
EventList::const_iterator const_iterator
boost::shared_ptr< SessionPlaylists > playlists
void audition_right_toggled()
framecnt_t length() const
virtual void set_session(ARDOUR::Session *)
virtual void add(double when, double value, bool with_guards=true, bool with_default=true)
Gtk::ToggleButton postroll_button
Gtk::ToggleButton audition_right_button
Glib::RefPtr< Gdk::Pixbuf > get_icon(const char *cname)
ArdourCanvas::PolyLine * curve
std::vector< Gtk::Button * > fade_out_buttons
LIBARDOUR_API PBD::PropertyDescriptor< float > scale_amplitude
static Presets * fade_out_presets
bool add(PropertyBase *prop)
ArdourCanvas::PolyLine * line
ARDOUR::Session * _session
void canvas_allocation(Gtk::Allocation &)
LIBARDOUR_API PBD::PropertyDescriptor< bool > fade_in_active
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
bool point_event(GdkEvent *event, Point *)
LIBARDOUR_API PBD::PropertyDescriptor< bool > color