Credit Andrew - fix vorbis audio which was scratchy and ensure aging plugin does...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / resample / resample.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcdisplayinfo.h"
23 #include "bchash.h"
24 #include "bcsignals.h"
25 #include "file.h"
26 #include "language.h"
27 #include "mainprogress.h"
28 #include "../../cinelerra/resample.h"
29 #include "resample.h"
30 #include "samples.h"
31 #include "transportque.inc"
32 #include "vframe.h"
33
34
35
36
37 PluginClient* new_plugin(PluginServer *server)
38 {
39         return new ResampleEffect(server);
40 }
41
42
43
44 ResampleFraction::ResampleFraction(ResampleEffect *plugin, int x, int y)
45  : BC_TextBox(x, y, xS(100), 1, (float)plugin->scale, 1, MEDIUMFONT, 6)
46 {
47         this->plugin = plugin;
48 }
49
50 int ResampleFraction::handle_event()
51 {
52         plugin->scale = atof(get_text());
53         return 1;
54 }
55
56
57
58
59
60
61
62
63 ResampleWindow::ResampleWindow(ResampleEffect *plugin, int x, int y)
64  : BC_Window(_(PROGRAM_NAME ": Resample"),
65                                 x - xS(160),
66                                 y - yS(75),
67                                 xS(320),
68                                 yS(150),
69                                 xS(320),
70                                 yS(150),
71                                 0,
72                                 0,
73                                 1)
74 {
75         this->plugin = plugin;
76 // *** CONTEXT_HELP ***
77         if(plugin) context_help_set_keyword(plugin->plugin_title());
78         else       context_help_set_keyword("Rendered Audio Effects");
79 }
80
81 void ResampleWindow::create_objects()
82 {
83         int xs10 = xS(10);
84         int ys10 = yS(10), ys20 = yS(20);
85         int x = xs10, y = ys10;
86         lock_window("ResampleWindow::create_objects");
87         add_subwindow(new BC_Title(x, y, _("Scale factor:")));
88         y += ys20;
89         add_subwindow(new ResampleFraction(plugin, x, y));
90         add_subwindow(new BC_OKButton(this));
91         add_subwindow(new BC_CancelButton(this));
92         show_window();
93         unlock_window();
94 }
95
96
97
98
99
100
101
102
103 ResampleResample::ResampleResample(ResampleEffect *plugin)
104 {
105         this->plugin = plugin;
106 }
107
108 int ResampleResample::read_samples(Samples *buffer, int64_t start, int64_t len)
109 {
110 //printf("ResampleResample::read_samples %d %lld\n", __LINE__, len);
111
112         return plugin->read_samples(buffer,
113                 0,
114                 start + plugin->get_source_start(),
115                 len);
116 }
117
118
119
120
121
122
123
124 ResampleEffect::ResampleEffect(PluginServer *server)
125  : PluginAClient(server)
126 {
127         reset();
128 }
129
130 ResampleEffect::~ResampleEffect()
131 {
132 }
133
134 const char* ResampleEffect::plugin_title() { return N_("Resample"); }
135
136 void ResampleEffect::reset()
137 {
138         resample = 0;
139 }
140
141 int ResampleEffect::get_parameters()
142 {
143         BC_DisplayInfo info;
144         ResampleWindow window(this, info.get_abs_cursor_x(), info.get_abs_cursor_y());
145         window.create_objects();
146         int result = window.run_window();
147
148         return result;
149 }
150
151
152 int ResampleEffect::load_defaults()
153 {
154         char directory[BCTEXTLEN];
155
156 // set the default directory
157         sprintf(directory, "%s/resample.rc", File::get_config_path());
158 // load the defaults
159         defaults = new BC_Hash(directory);
160         defaults->load();
161
162         scale = defaults->get("SCALE", (double)1);
163 //printf("ResampleEffect::load_defaults %d %f\n", __LINE__, scale);
164         return 0;
165 }
166
167 int ResampleEffect::save_defaults()
168 {
169 //printf("ResampleEffect::save_defaults %d %f\n", __LINE__, scale);
170         defaults->update("SCALE", scale);
171         defaults->save();
172         return 0;
173 }
174
175
176
177 int ResampleEffect::start_loop()
178 {
179         if(PluginClient::interactive)
180         {
181                 char string[BCTEXTLEN];
182                 sprintf(string, "%s...", plugin_title());
183                 progress = start_progress(string,
184                         (int64_t)((double)(PluginClient::end - PluginClient::start) / scale));
185         }
186
187         current_position = PluginClient::start;
188         total_written = 0;
189
190         resample = new ResampleResample(this);
191         return 0;
192 }
193
194 int ResampleEffect::stop_loop()
195 {
196         if(PluginClient::interactive)
197         {
198                 progress->stop_progress();
199                 delete progress;
200         }
201         return 0;
202 }
203
204 int ResampleEffect::process_loop(Samples *buffer, int64_t &write_length)
205 {
206         int result = 0;
207
208 // Length to read based on desired output size
209 //printf("ResampleEffect::process_loop %d %d\n", __LINE__);
210 //      int64_t size = (int64_t)((double)PluginAClient::in_buffer_size * scale);
211         int64_t predicted_total = (int64_t)((double)(PluginClient::end - PluginClient::start) / scale + 0.5);
212
213 //      Samples *input = new Samples(size);
214
215 //      read_samples(input, 0, current_position, size);
216 //      current_position += size;
217
218         resample->resample(buffer,
219                 PluginAClient::out_buffer_size,
220                 1000000,
221                 (int)(1000000.0 / scale),
222                 total_written,
223                 PLAY_FORWARD);
224
225         write_length = PluginAClient::out_buffer_size;
226         if(total_written + write_length >= predicted_total)
227         {
228                 write_length = predicted_total - total_written;
229                 result = 1;
230         }
231         total_written += write_length;
232 //printf("ResampleEffect::process_loop %d %lld %f\n", __LINE__, write_length, scale);
233
234 //      resample->resample_chunk(input,
235 //              size,
236 //              1000000,
237 //              (int)(1000000.0 / scale),
238 //              0);
239 //
240 // //
241 //      if(resample->get_output_size(0))
242 //      {
243 //              int64_t output_size = resample->get_output_size(0);
244 //
245 // //           if(output_size)
246 //              {
247 //                      total_written += output_size;
248 //              }
249 //
250 // // // Trim output to predicted length of stretched selection.
251 //              if(total_written > predicted_total)
252 //              {
253 //                      output_size -= total_written - predicted_total;
254 //                      result = 1;
255 //              }
256 //
257 // //           resample->read_output(buffer, 0, output_size);
258 //
259 // //           write_length = output_size;
260 //      }
261
262         if(PluginClient::interactive) result |= progress->update(total_written);
263 //printf("ResampleEffect::process_loop %d %lld\n", __LINE__, total_written);
264
265 //      delete input;
266         return result;
267 }
268
269
270
271
272
273
274
275
276
277
278
279