update internationalization data
[goodguy/history.git] / cinelerra-5.0 / 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()
97 {
98         return _("Interpolate");
99 }
100
101
102 int InterpolateAudioEffect::is_realtime()
103 {
104         return 1;
105 }
106
107
108
109
110
111 int InterpolateAudioEffect::process_buffer(int64_t size, 
112         Samples *buffer,
113         int64_t start_position,
114         int sample_rate)
115 {
116         if(!start_fragment) start_fragment = new Samples(FRAGMENT_SIZE);
117         if(!end_fragment) end_fragment = new Samples(FRAGMENT_SIZE);
118         double *buffer_samples = buffer->get_data();
119         double *start_samples = start_fragment->get_data();
120         double *end_samples = end_fragment->get_data();
121
122         if(get_direction() == PLAY_FORWARD)
123         {
124 // On first sample of range.  Get boundary samples of effect.
125                 if(get_source_position() == get_source_start())
126                 {
127 // Need to read before desired sample to diffuse transients after audio
128 // seeks.
129                         range_start = get_source_start();
130                         range_end = get_source_start() + get_total_len();
131 //printf("InterpolateAudioEffect::process_buffer 1 %p\n", start_fragment);
132                         read_samples(start_fragment,
133                                 0,
134                                 sample_rate,
135                                 range_start - FRAGMENT_SIZE,
136                                 FRAGMENT_SIZE);
137                         start_sample = start_samples[FRAGMENT_SIZE - 1];
138                         read_samples(end_fragment,
139                                 0,
140                                 sample_rate,
141                                 range_end - FRAGMENT_SIZE,
142                                 FRAGMENT_SIZE);
143                         end_sample = end_samples[FRAGMENT_SIZE - 1];
144                 }
145
146
147                 for(int i = 0; i < size; i++)
148                 {
149                         double end_fraction = (double)(i + start_position - range_start) / 
150                                 (range_end - range_start);
151                         double start_fraction = 1.0 - end_fraction;
152                         double out_sample = start_sample * start_fraction + 
153                                 end_sample * end_fraction;
154                         buffer_samples[i] = out_sample;
155                 }
156         }
157         else
158         {
159 // On first sample of range.  Get boundary samples of effect.
160                 if(get_source_position() == get_source_start() + get_total_len())
161                 {
162 // Need to read before desired sample to diffuse transients after audio
163 // seeks.
164                         range_start = get_source_start() + get_total_len();
165                         range_end = get_source_start();
166                         read_samples(start_fragment,
167                                 0,
168                                 sample_rate,
169                                 range_start,
170                                 FRAGMENT_SIZE);
171                         start_sample = start_samples[0];
172                         read_samples(end_fragment,
173                                 0,
174                                 sample_rate,
175                                 range_end,
176                                 FRAGMENT_SIZE);
177                         end_sample = end_samples[0];
178                 }
179
180
181                 for(int i = 0; i < size; i++)
182                 {
183                         double start_fraction = (double)(start_position - i - range_end) / 
184                                 (range_start - range_end);
185                         double end_fraction = 1.0 - start_fraction;
186                         double out_sample = start_sample * start_fraction + 
187                                 end_sample * end_fraction;
188                         buffer_samples[i] = out_sample;
189                 }
190         }
191         return 0;
192 }
193
194