4 * Copyright (C) 2008 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"
28 #include "mainprogress.h"
29 #include "pluginaclient.h"
31 #include "transportque.h"
46 class InterpolateAudioEffect : public PluginAClient
49 InterpolateAudioEffect(PluginServer *server);
50 ~InterpolateAudioEffect();
52 const char* plugin_title();
54 int process_buffer(int64_t size,
56 int64_t start_position,
60 #define FRAGMENT_SIZE 4096
61 Samples *start_fragment;
62 Samples *end_fragment;
72 REGISTER_PLUGIN(InterpolateAudioEffect)
80 InterpolateAudioEffect::InterpolateAudioEffect(PluginServer *server)
81 : PluginAClient(server)
87 InterpolateAudioEffect::~InterpolateAudioEffect()
89 if(start_fragment) delete start_fragment;
90 if(end_fragment) delete end_fragment;
96 const char* InterpolateAudioEffect::plugin_title() { return N_("Interpolate"); }
97 int InterpolateAudioEffect::is_realtime() { return 1; }
103 int InterpolateAudioEffect::process_buffer(int64_t size,
105 int64_t start_position,
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();
114 if(get_direction() == PLAY_FORWARD)
116 // On first sample of range. Get boundary samples of effect.
117 if(get_source_position() == get_source_start())
119 // Need to read before desired sample to diffuse transients after audio
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,
127 range_start - FRAGMENT_SIZE,
129 start_sample = start_samples[FRAGMENT_SIZE - 1];
130 read_samples(end_fragment,
133 range_end - FRAGMENT_SIZE,
135 end_sample = end_samples[FRAGMENT_SIZE - 1];
139 for(int i = 0; i < size; i++)
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;
151 // On first sample of range. Get boundary samples of effect.
152 if(get_source_position() == get_source_start() + get_total_len())
154 // Need to read before desired sample to diffuse transients after audio
156 range_start = get_source_start() + get_total_len();
157 range_end = get_source_start();
158 read_samples(start_fragment,
163 start_sample = start_samples[0];
164 read_samples(end_fragment,
169 end_sample = end_samples[0];
173 for(int i = 0; i < size; i++)
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;