preview tooltip, ffv1 fmt, opengl overlay tweaks, clear nested render output bfr
[goodguy/history.git] / cinelerra-5.1 / plugins / interpolateaudio / interpolateaudio.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 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 "clip.h"
24 #include "bchash.h"
25 #include "guicast.h"
26 #include "filexml.h"
27 #include "language.h"
28 #include "mainprogress.h"
29 #include "pluginaclient.h"
30 #include "samples.h"
31 #include "transportque.h"
32
33 #include <string.h>
34
35
36
37
38
39
40
41
42
43
44
45
46 class InterpolateAudioEffect : public PluginAClient
47 {
48 public:
49         InterpolateAudioEffect(PluginServer *server);
50         ~InterpolateAudioEffect();
51
52         const char* plugin_title();
53
54         int process_buffer(int64_t size,
55                 Samples *buffer,
56                 int64_t start_position,
57                 int sample_rate);
58         int is_realtime();
59
60 #define FRAGMENT_SIZE 4096
61         Samples *start_fragment;
62         Samples *end_fragment;
63         double start_sample;
64         double end_sample;
65         int64_t range_start;
66         int64_t range_end;
67 };
68
69
70
71
72 REGISTER_PLUGIN(InterpolateAudioEffect)
73
74
75
76
77
78
79
80 InterpolateAudioEffect::InterpolateAudioEffect(PluginServer *server)
81  : PluginAClient(server)
82 {
83         start_fragment = 0;
84         end_fragment = 0;
85 }
86
87 InterpolateAudioEffect::~InterpolateAudioEffect()
88 {
89         if(start_fragment) delete start_fragment;
90         if(end_fragment) delete end_fragment;
91 }
92
93
94
95
96 const char* InterpolateAudioEffect::plugin_title() { return N_("Interpolate"); }
97 int InterpolateAudioEffect::is_realtime() { return 1; }
98
99
100
101
102
103 int InterpolateAudioEffect::process_buffer(int64_t size,
104         Samples *buffer,
105         int64_t start_position,
106         int sample_rate)
107 {
108         if(!start_fragment) start_fragment = new Samples(FRAGMENT_SIZE);
109         if(!end_fragment) end_fragment = new Samples(FRAGMENT_SIZE);
110         double *buffer_samples = buffer->get_data();
111         double *start_samples = start_fragment->get_data();
112         double *end_samples = end_fragment->get_data();
113
114         if(get_direction() == PLAY_FORWARD)
115         {
116 // On first sample of range.  Get boundary samples of effect.
117                 if(get_source_position() == get_source_start())
118                 {
119 // Need to read before desired sample to diffuse transients after audio
120 // seeks.
121                         range_start = get_source_start();
122                         range_end = get_source_start() + get_total_len();
123 //printf("InterpolateAudioEffect::process_buffer 1 %p\n", start_fragment);
124                         read_samples(start_fragment,
125                                 0,
126                                 sample_rate,
127                                 range_start - FRAGMENT_SIZE,
128                                 FRAGMENT_SIZE);
129                         start_sample = start_samples[FRAGMENT_SIZE - 1];
130                         read_samples(end_fragment,
131                                 0,
132                                 sample_rate,
133                                 range_end - FRAGMENT_SIZE,
134                                 FRAGMENT_SIZE);
135                         end_sample = end_samples[FRAGMENT_SIZE - 1];
136                 }
137
138
139                 for(int i = 0; i < size; i++)
140                 {
141                         double end_fraction = (double)(i + start_position - range_start) /
142                                 (range_end - range_start);
143                         double start_fraction = 1.0 - end_fraction;
144                         double out_sample = start_sample * start_fraction +
145                                 end_sample * end_fraction;
146                         buffer_samples[i] = out_sample;
147                 }
148         }
149         else
150         {
151 // On first sample of range.  Get boundary samples of effect.
152                 if(get_source_position() == get_source_start() + get_total_len())
153                 {
154 // Need to read before desired sample to diffuse transients after audio
155 // seeks.
156                         range_start = get_source_start() + get_total_len();
157                         range_end = get_source_start();
158                         read_samples(start_fragment,
159                                 0,
160                                 sample_rate,
161                                 range_start,
162                                 FRAGMENT_SIZE);
163                         start_sample = start_samples[0];
164                         read_samples(end_fragment,
165                                 0,
166                                 sample_rate,
167                                 range_end,
168                                 FRAGMENT_SIZE);
169                         end_sample = end_samples[0];
170                 }
171
172
173                 for(int i = 0; i < size; i++)
174                 {
175                         double start_fraction = (double)(start_position - i - range_end) /
176                                 (range_start - range_end);
177                         double end_fraction = 1.0 - start_fraction;
178                         double out_sample = start_sample * start_fraction +
179                                 end_sample * end_fraction;
180                         buffer_samples[i] = out_sample;
181                 }
182         }
183         return 0;
184 }
185
186