4 * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "bcdisplayinfo.h"
26 #include "resamplert.h"
28 #include "transportque.h"
38 REGISTER_PLUGIN(ResampleRT);
42 ResampleRTConfig::ResampleRTConfig()
48 int ResampleRTConfig::equivalent(ResampleRTConfig &src)
50 return fabs(scale - src.scale) < 0.0001;
53 void ResampleRTConfig::copy_from(ResampleRTConfig &src)
55 this->scale = src.scale;
58 void ResampleRTConfig::interpolate(ResampleRTConfig &prev,
59 ResampleRTConfig &next,
62 int64_t current_frame)
64 this->scale = prev.scale;
67 void ResampleRTConfig::boundaries()
69 if(fabs(scale) < 0.0001) scale = 0.0001;
75 ResampleRTWindow::ResampleRTWindow(ResampleRT *plugin)
76 : PluginClientWindow(plugin,
83 this->plugin = plugin;
86 ResampleRTWindow::~ResampleRTWindow()
90 void ResampleRTWindow::create_objects()
95 add_subwindow(title = new BC_Title(x, y, _("Scale by amount:")));
96 y += title->get_h() + plugin->get_theme()->widget_border;
98 scale = new ResampleRTScale(this,
102 scale->create_objects();
111 ResampleRTScale::ResampleRTScale(ResampleRTWindow *window,
115 : BC_TumbleTextBox(window,
116 plugin->config.scale,
123 this->plugin = plugin;
124 set_increment(0.001);
127 int ResampleRTScale::handle_event()
129 plugin->config.scale = atof(get_text());
130 plugin->send_configure_change();
139 ResampleRTResample::ResampleRTResample(ResampleRT *plugin)
142 this->plugin = plugin;
145 // To get the keyframes to work, resampling is always done in the forward
146 // direction with the plugin converting to reverse.
147 int ResampleRTResample::read_samples(Samples *buffer,
151 int result = plugin->read_samples(buffer,
153 plugin->get_samplerate(),
154 plugin->source_start,
157 //printf("ResampleRTResample::read_samples %lld %lld %lld %d\n", start, plugin->source_start, len, result);
158 if(plugin->get_direction() == PLAY_FORWARD)
159 plugin->source_start += len;
161 plugin->source_start -= len;
171 ResampleRT::ResampleRT(PluginServer *server)
172 : PluginAClient(server)
175 need_reconfigure = 1;
181 ResampleRT::~ResampleRT()
186 const char* ResampleRT::plugin_title() { return _("ResampleRT"); }
187 int ResampleRT::is_realtime() { return 1; }
188 int ResampleRT::is_synthesis() { return 1; }
191 NEW_WINDOW_MACRO(ResampleRT, ResampleRTWindow)
193 LOAD_CONFIGURATION_MACRO(ResampleRT, ResampleRTConfig)
196 int ResampleRT::process_buffer(int64_t size,
198 int64_t start_position,
201 if(!resample) resample = new ResampleRTResample(this);
203 need_reconfigure |= load_configuration();
206 if(start_position != dest_start) need_reconfigure = 1;
207 dest_start = start_position;
209 // Get start position of the input.
210 // Sample 0 is the keyframe position
213 int64_t prev_position = edl_to_local(
215 get_source_position())->position);
217 if(prev_position == 0)
219 prev_position = get_source_start();
222 source_start = (int64_t)((start_position - prev_position) *
223 config.scale) + prev_position;
226 need_reconfigure = 0;
229 resample->resample(buffer,
232 (int)(1000000 / config.scale),
236 if(get_direction() == PLAY_FORWARD)
244 void ResampleRT::render_stop()
246 need_reconfigure = 1;
252 void ResampleRT::save_data(KeyFrame *keyframe)
256 // cause data to be stored directly in text
257 output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
258 output.tag.set_title("RESAMPLERT");
259 output.tag.set_property("SCALE", config.scale);
261 output.tag.set_title("/RESAMPLERT");
263 output.append_newline();
264 output.terminate_string();
267 void ResampleRT::read_data(KeyFrame *keyframe)
271 input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
273 while(!input.read_tag())
275 if(input.tag.title_is("RESAMPLERT"))
277 config.scale = input.tag.get_property("SCALE", config.scale);
282 void ResampleRT::update_gui()
286 if(load_configuration())
288 thread->window->lock_window("ResampleRT::update_gui");
289 ((ResampleRTWindow*)thread->window)->scale->update((float)config.scale);
290 thread->window->unlock_window();