Make send automation work (#4734).
[ardour.git] / gtk2_ardour / time_fx_dialog.cc
1 /*
2     Copyright (C) 2000-2009 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include "time_fx_dialog.h"
21
22 #include <iostream>
23 #include <cstdlib>
24 #include <cmath>
25
26 #include <string>
27
28 #include "pbd/error.h"
29 #include "pbd/pthread_utils.h"
30 #include "pbd/memento_command.h"
31
32 #include <gtkmm2ext/utils.h>
33
34 #include "editor.h"
35 #include "audio_time_axis.h"
36 #include "audio_region_view.h"
37 #include "region_selection.h"
38
39 #ifdef USE_RUBBERBAND
40 #include "rubberband/RubberBandStretcher.h"
41 using namespace RubberBand;
42 #endif
43
44 #include "i18n.h"
45
46 using namespace std;
47 using namespace ARDOUR;
48 using namespace PBD;
49 using namespace Gtk;
50 using namespace Gtkmm2ext;
51
52 TimeFXDialog::TimeFXDialog (Editor& e, bool pitch)
53         : ArdourDialog (X_("time fx dialog"))
54         , editor (e)
55         , pitching (pitch)
56         , pitch_octave_adjustment (0.0, -4.0, 4.0, 1, 2.0)
57         , pitch_semitone_adjustment (0.0, -12.0, 12.0, 1.0, 4.0)
58         , pitch_cent_adjustment (0.0, -499.0, 500.0, 5.0, 15.0)
59         , pitch_octave_spinner (pitch_octave_adjustment)
60         , pitch_semitone_spinner (pitch_semitone_adjustment)
61         , pitch_cent_spinner (pitch_cent_adjustment)
62         , quick_button (_("Quick but Ugly"))
63         , antialias_button (_("Skip Anti-aliasing"))
64         , stretch_opts_label (_("Contents:"))
65         , precise_button (_("Minimize time distortion"))
66         , preserve_formants_button(_("Preserve Formants"))
67 {
68         set_modal (true);
69         set_skip_taskbar_hint (true);
70         set_resizable (false);
71         set_position (Gtk::WIN_POS_MOUSE);
72         set_name (N_("TimeFXDialog"));
73
74         if (pitching) {
75                 set_title (_("Pitch Shift Audio"));
76         } else {
77                 set_title (_("Time Stretch Audio"));
78         }
79
80         cancel_button = add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
81
82         VBox* vbox = manage (new VBox);
83         Gtk::Label* l;
84
85         get_vbox()->set_spacing (4);
86
87         vbox->set_spacing (18);
88         vbox->set_border_width (5);
89
90         upper_button_box.set_spacing (6);
91
92         l = manage (new Label (_("<b>Options</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false ));
93         l->set_use_markup ();
94
95         upper_button_box.pack_start (*l, false, false);
96
97         if (pitching) {
98                 Table* table = manage (new Table (4, 3, false));
99                 table->set_row_spacings (6);
100                 table->set_col_spacing  (1, 6);
101                 l = manage (new Label ("", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false )); //Common gnome way for padding
102                 l->set_padding (8, 0);
103                 table->attach (*l, 0, 1, 0, 4, Gtk::FILL, Gtk::FILL, 0, 0);
104
105                 l = manage (new Label (_("Octaves:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
106                 table->attach (*l, 1, 2, 0, 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
107                 table->attach (pitch_octave_spinner, 2, 3, 0, 1, Gtk::FILL, Gtk::EXPAND & Gtk::FILL, 0, 0);
108                 pitch_octave_spinner.set_activates_default ();
109
110                 l = manage (new Label (_("Semitones:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
111                 table->attach (*l, 1, 2, 1, 2, Gtk::FILL, Gtk::EXPAND, 0, 0);
112                 table->attach (pitch_semitone_spinner, 2, 3, 1, 2, Gtk::FILL, Gtk::EXPAND & Gtk::FILL, 0, 0);
113                 pitch_semitone_spinner.set_activates_default ();
114
115                 l = manage (new Label (_("Cents:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
116                 pitch_cent_spinner.set_digits (1);
117                 table->attach (*l, 1, 2, 2, 3, Gtk::FILL, Gtk::EXPAND, 0, 0);
118                 table->attach (pitch_cent_spinner, 2, 3, 2, 3, Gtk::FILL, Gtk::EXPAND & Gtk::FILL, 0, 0);
119                 pitch_cent_spinner.set_activates_default ();
120
121                 table->attach (preserve_formants_button, 1, 3, 3, 4, Gtk::FILL, Gtk::EXPAND, 0, 0);
122
123                 add_button (S_("Time|Shift"), Gtk::RESPONSE_ACCEPT);
124
125                 upper_button_box.pack_start (*table, false, true);
126         } else {
127                 Table* table = manage (new Table (2, 3, false));
128                 table->set_row_spacings (6);
129                 table->set_col_spacing  (1, 6);
130                 l = manage (new Label ("", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false ));
131                 l->set_padding (8, 0);
132                 table->attach (*l, 0, 1, 0, 2, Gtk::FILL, Gtk::FILL, 0, 0);
133
134 #ifdef USE_RUBBERBAND
135                 vector<string> strings;
136
137                 table->attach (stretch_opts_label, 1, 2, 0, 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
138
139                 set_popdown_strings (stretch_opts_selector, editor.rb_opt_strings);
140                 /* set default */
141                 stretch_opts_selector.set_active_text (editor.rb_opt_strings[editor.rb_current_opt]);
142                 table->attach (stretch_opts_selector, 2, 3, 0, 1, Gtk::FILL, Gtk::EXPAND & Gtk::FILL, 0, 0);
143
144                 table->attach (precise_button, 1, 3, 1, 2, Gtk::FILL, Gtk::EXPAND, 0, 0);
145
146 #else
147                 quick_button.set_name (N_("TimeFXButton"));
148                 table->attach (quick_button, 1, 3, 0, 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
149
150                 antialias_button.set_name (N_("TimeFXButton"));
151                 table->attach (antialias_button, 1, 3, 1, 2, Gtk::FILL, Gtk::EXPAND, 0, 0);
152
153 #endif
154
155                 add_button (_("Stretch/Shrink"), Gtk::RESPONSE_ACCEPT);
156
157                 upper_button_box.pack_start (*table, false, true);
158         }
159
160         set_default_response (Gtk::RESPONSE_ACCEPT);
161         
162         VBox* progress_box = manage (new VBox);
163         progress_box->set_spacing (6);
164
165         l = manage (new Label (_("<b>Progress</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
166         l->set_use_markup ();
167
168         progress_box->pack_start (*l, false, false);
169         progress_box->pack_start (progress_bar, false, true);
170
171
172         vbox->pack_start (upper_button_box, false, true);
173         vbox->pack_start (*progress_box, false, true);
174
175         get_vbox()->pack_start (*vbox, false, false);
176
177         show_all_children ();
178 }
179
180 void
181 TimeFXDialog::update_progress_gui (float p)
182 {
183         progress_bar.set_fraction (p);
184 }
185
186 void
187 TimeFXDialog::cancel_in_progress ()
188 {
189         status = -2;
190         request.cancel = true;
191         first_cancel.disconnect();
192 }
193
194 gint
195 TimeFXDialog::delete_in_progress (GdkEventAny*)
196 {
197         status = -2;
198         request.cancel = true;
199         first_delete.disconnect();
200         return TRUE;
201 }
202