merged hv7 mod
[goodguy/history.git] / cinelerra-5.1 / plugins / timestretchrt / timestretchrt.C
index d4382b2700963c6a8ecd036f9c9d86019205d3d4..89b7efa4bc3a47a4b475a8327235d26faa91f080 100644 (file)
@@ -2,21 +2,21 @@
 /*
  * CINELERRA
  * Copyright (C) 2011 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
 #include "bcdisplayinfo.h"
@@ -42,37 +42,48 @@ REGISTER_PLUGIN(TimeStretchRT);
 
 TimeStretchRTConfig::TimeStretchRTConfig()
 {
-       scale = 1;
+//     scale = 1;
+       num = 1;
+       denom = 1;
        size = 40;
 }
 
 
 int TimeStretchRTConfig::equivalent(TimeStretchRTConfig &src)
 {
-       return fabs(scale - src.scale) < 0.0001 && size == src.size;
+//     return fabs(scale - src.scale) < 0.0001 && size == src.size;
+       return fabs(num - src.num) < 0.0001 &&
+               fabs(denom - src.denom) < 0.0001 && 
+               size == src.size;
 }
 
 void TimeStretchRTConfig::copy_from(TimeStretchRTConfig &src)
 {
-       this->scale = src.scale;
+       this->num = src.num;
+       this->denom = src.denom;
+//     this->scale = src.scale;
        this->size = src.size;
 }
 
-void TimeStretchRTConfig::interpolate(TimeStretchRTConfig &prev, 
-       TimeStretchRTConfig &next, 
-       int64_t prev_frame, 
-       int64_t next_frame, 
+void TimeStretchRTConfig::interpolate(TimeStretchRTConfig &prev,
+       TimeStretchRTConfig &next,
+       int64_t prev_frame,
+       int64_t next_frame,
        int64_t current_frame)
 {
-       this->scale = prev.scale;
+       this->num = prev.num;
+       this->denom = prev.denom;
+//     this->scale = prev.scale;
        this->size = prev.size;
        boundaries();
 }
 
 void TimeStretchRTConfig::boundaries()
 {
-       if(fabs(scale) < 0.01) scale = 0.01;
-       if(fabs(scale) > 100) scale = 100;
+       if(num < 0.0001) num = 0.0001;
+       if(denom < 0.0001) denom = 0.0001;
+//     if(fabs(scale) < 0.01) scale = 0.01;
+//     if(fabs(scale) > 100) scale = 100;
        if(size < 10) size = 10;
        if(size > 1000) size = 1000;
 }
@@ -81,11 +92,11 @@ void TimeStretchRTConfig::boundaries()
 
 
 TimeStretchRTWindow::TimeStretchRTWindow(TimeStretchRT *plugin)
- : PluginClientWindow(plugin, 
+ : PluginClientWindow(plugin,
        210, 
-       160, 
        200, 
-       160, 
+       200, 
+       210,
        0)
 {
        this->plugin = plugin;
@@ -98,22 +109,34 @@ TimeStretchRTWindow::~TimeStretchRTWindow()
 void TimeStretchRTWindow::create_objects()
 {
        int x = 10, y = 10;
+       int margin = plugin->get_theme()->widget_border;
 
        BC_Title *title = 0;
-       add_subwindow(title = new BC_Title(x, y, _("Fraction of original speed:")));
+       add_subwindow(title = new BC_Title(x, y, _("Input samples:")));
        y += title->get_h() + plugin->get_theme()->widget_border;
-       scale = new TimeStretchRTScale(this,
+       num = new TimeStretchRTScale(this,
                plugin, 
                x, 
-               y);
-       scale->create_objects();
-       
-       y += scale->get_h() + plugin->get_theme()->widget_border;
-       add_subwindow(title = new BC_Title(x, y, _("Window size (ms):")));
+               y,
+               &plugin->config.num);
+       num->create_objects();
+       y += num->get_h() + margin;
+
+       add_subwindow(title = new BC_Title(x, y, _("Output samples:")));
        y += title->get_h() + plugin->get_theme()->widget_border;
-       size = new TimeStretchRTSize(this,
+       denom = new TimeStretchRTScale(this,
                plugin, 
                x, 
+               y,
+               &plugin->config.denom);
+       denom->create_objects();
+
+       y += denom->get_h() + margin;
+       add_subwindow(title = new BC_Title(x, y, _("Window size (ms):")));
+       y += title->get_h() + margin;
+       size = new TimeStretchRTSize(this,
+               plugin,
+               x,
                y);
        size->create_objects();
 
@@ -126,24 +149,27 @@ void TimeStretchRTWindow::create_objects()
 
 
 TimeStretchRTScale::TimeStretchRTScale(TimeStretchRTWindow *window,
-       TimeStretchRT *plugin, 
-       int x, 
-       int y)
+       TimeStretchRT *plugin,
+       int x,
+       int y,
+       double *value)
  : BC_TumbleTextBox(window,
-       (float)(1.0 / plugin->config.scale),
+       (float)*value,
        (float)0.0001,
        (float)1000,
-       x, 
-       y, 
+       x,
+       y,
        100)
 {
        this->plugin = plugin;
+       this->value = value;
        set_increment(0.01);
 }
 
 int TimeStretchRTScale::handle_event()
 {
-       plugin->config.scale = 1.0 / atof(get_text());
+       *value = atof(get_text());
+       plugin->config.boundaries();
        plugin->send_configure_change();
        return 1;
 }
@@ -152,15 +178,15 @@ int TimeStretchRTScale::handle_event()
 
 
 TimeStretchRTSize::TimeStretchRTSize(TimeStretchRTWindow *window,
-       TimeStretchRT *plugin, 
-       int x, 
+       TimeStretchRT *plugin,
+       int x,
        int y)
  : BC_TumbleTextBox(window,
        plugin->config.size,
        10,
        1000,
-       x, 
-       y, 
+       x,
+       y,
        100)
 {
        this->plugin = plugin;
@@ -206,14 +232,14 @@ NEW_WINDOW_MACRO(TimeStretchRT, TimeStretchRTWindow)
 LOAD_CONFIGURATION_MACRO(TimeStretchRT, TimeStretchRTConfig)
 
 
-int TimeStretchRT::process_buffer(int64_t size, 
+int TimeStretchRT::process_buffer(int64_t size,
        Samples *buffer,
        int64_t start_position,
        int sample_rate)
 {
        need_reconfigure = load_configuration();
 
-       if(!engine) engine = new TimeStretchEngine(config.scale
+       if(!engine) engine = new TimeStretchEngine(config.denom / config.num
                sample_rate,
                config.size);
 
@@ -222,7 +248,6 @@ int TimeStretchRT::process_buffer(int64_t size,
 
 // Get start position of the input.
 // Sample 0 is the keyframe position
-//printf("TimeStretchRT::process_buffer %d %f\n", __LINE__, config.scale);
        if(need_reconfigure)
        {
                int64_t prev_position = edl_to_local(
@@ -234,15 +259,18 @@ int TimeStretchRT::process_buffer(int64_t size,
                        prev_position = get_source_start();
                }
 
-               source_start = (int64_t)((start_position - prev_position) / 
-                       config.scale) + prev_position;
+               source_start = (int64_t)((start_position - prev_position) * 
+                       config.num / config.denom) + prev_position;
 
                engine->reset();
-               engine->update(config.scale, sample_rate, config.size);
+               engine->update(config.denom / config.num, sample_rate, config.size);
                need_reconfigure = 0;
-//printf("TimeStretchRT::process_buffer %d start_position=" _LD
-//      " prev_position=%jd scale=%f source_start=%jd\n", 
-//     __LINE__, start_position, prev_position, config.scale, source_start);
+// printf("TimeStretchRT::process_buffer %d start_position=%lld prev_position=%lld scale=%f source_start=%lld\n", 
+// __LINE__, 
+// start_position,
+// prev_position,
+// config.scale,
+// source_start);
        }
 
 // process buffers until output length is reached
@@ -250,7 +278,7 @@ int TimeStretchRT::process_buffer(int64_t size,
        while(!error && engine->get_output_size() < size)
        {
 
-// printf("TimeStretchRT::process_buffer %d buffer=%p size=%lld source_start=%lld\n", 
+// printf("TimeStretchRT::process_buffer %d buffer=%p size=%lld source_start=%lld\n",
 // __LINE__,
 // buffer,
 // size,
@@ -260,13 +288,13 @@ int TimeStretchRT::process_buffer(int64_t size,
                        sample_rate,
                        source_start,
                        size);
-               
+
 
                if(get_direction() == PLAY_FORWARD)
                        source_start += size;
                else
                        source_start -= size;
-                       
+
 //printf("TimeStretchRT::process_buffer %d size=%d\n", __LINE__, size);
                engine->process(buffer, size);
 //printf("TimeStretchRT::process_buffer %d\n", __LINE__);
@@ -297,7 +325,8 @@ void TimeStretchRT::save_data(KeyFrame *keyframe)
 // cause data to be stored directly in text
        output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
        output.tag.set_title("TIMESTRETCHRT");
-       output.tag.set_property("SCALE", config.scale);
+       output.tag.set_property("NUM", config.num);
+       output.tag.set_property("DENOM", config.denom);
        output.tag.set_property("SIZE", config.size);
        output.append_tag();
        output.tag.set_title("/TIMESTRETCHRT");
@@ -316,7 +345,8 @@ void TimeStretchRT::read_data(KeyFrame *keyframe)
        {
                if(input.tag.title_is("TIMESTRETCHRT"))
                {
-                       config.scale = input.tag.get_property("SCALE", config.scale);
+                       config.num = input.tag.get_property("NUM", config.num);
+                       config.denom = input.tag.get_property("DENOM", config.denom);
                        config.size = input.tag.get_property("SIZE", config.size);
                }
        }
@@ -328,9 +358,10 @@ void TimeStretchRT::update_gui()
        {
                if(load_configuration())
                {
-               
+
                        thread->window->lock_window("TimeStretchRT::update_gui");
-                       ((TimeStretchRTWindow*)thread->window)->scale->update((float)(1.0 / config.scale));
+                       ((TimeStretchRTWindow*)thread->window)->num->update((float)config.num);
+                       ((TimeStretchRTWindow*)thread->window)->denom->update((float)config.denom);
                        ((TimeStretchRTWindow*)thread->window)->size->update((int64_t)config.size);
                        thread->window->unlock_window();
                }