8 #define WINDOW_BORDER (window_size / 2)
19 int FFT::do_fft(unsigned int samples, // must be a power of 2
20 int inverse, // 0 = forward FFT, 1 = inverse
21 double *real_in, // array of input's real samples
22 double *imag_in, // array of input's imag samples
23 double *real_out, // array of output's reals
26 unsigned int num_bits; // Number of bits needed to store indices
27 unsigned int i, j, k, n;
28 unsigned int block_size, block_end;
30 double angle_numerator = 2.0 * M_PI;
31 double tr, ti; // temp real, temp imaginary
34 angle_numerator = -angle_numerator;
36 num_bits = samples_to_bits(samples);
38 // Do simultaneous data copy and bit-reversal ordering into outputs
40 for(i = 0; i < samples; i++)
42 j = reverse_bits(i, num_bits);
43 real_out[j] = real_in[i];
44 imag_out[j] = (imag_in == 0) ? 0.0 : imag_in[i];
58 for(block_size = 2; block_size <= samples; block_size <<= 1)
60 delta_angle = angle_numerator / (double)block_size;
61 sm2 = sin(-2 * delta_angle);
62 sm1 = sin(-delta_angle);
63 cm2 = cos(-2 * delta_angle);
64 cm1 = cos(-delta_angle);
67 for(i = 0; i < samples; i += block_size)
75 for(j = i, n = 0; n < block_end; j++, n++)
77 ar[0] = w * ar[1] - ar[2];
81 ai[0] = w * ai[1] - ai[2];
86 tr = ar[0] * real_out[k] - ai[0] * imag_out[k];
87 ti = ar[0] * imag_out[k] + ai[0] * real_out[k];
89 real_out[k] = real_out[j] - tr;
90 imag_out[k] = imag_out[j] - ti;
97 block_end = block_size;
100 // Normalize if inverse transform
104 double denom = (double)samples;
106 for (i = 0; i < samples; i++)
108 real_out[i] /= denom;
109 imag_out[i] /= denom;
116 unsigned int FFT::samples_to_bits(unsigned int samples)
122 if(samples & (1 << i))
128 unsigned int FFT::reverse_bits(unsigned int index, unsigned int bits)
132 for(i = rev = 0; i < bits; i++)
134 rev = (rev << 1) | (index & 1);
141 int FFT::symmetry(int size, double *freq_real, double *freq_imag)
144 for(int i = h + 1; i < size; i++)
146 freq_real[i] = freq_real[size - i];
147 freq_imag[i] = -freq_imag[size - i];
156 CrossfadeFFT::CrossfadeFFT() : FFT()
162 CrossfadeFFT::~CrossfadeFFT()
167 int CrossfadeFFT::reset()
176 input_size = 0; // samples in input_buffer and output_buffer
178 input_allocation = 0;
179 output_allocation = 0;
183 int CrossfadeFFT::delete_fft()
185 if(input_buffer) delete [] input_buffer;
186 if(output_buffer) delete [] output_buffer;
187 if(freq_real) delete [] freq_real;
188 if(freq_imag) delete [] freq_imag;
189 if(temp_real) delete [] temp_real;
190 if(temp_imag) delete [] temp_imag;
195 int CrossfadeFFT::fix_window_size()
197 // fix the window size
198 // window size must be a power of 2
200 while(new_size < window_size) new_size *= 2;
201 window_size = MIN(131072, window_size);
202 window_size = new_size;
206 int CrossfadeFFT::initialize(int window_size)
208 this->window_size = window_size;
214 long CrossfadeFFT::get_delay()
216 return window_size + WINDOW_BORDER;
219 int CrossfadeFFT::reconfigure()
229 int CrossfadeFFT::process_fifo(long size, double *input_ptr, double *output_ptr)
231 //printf("CrossfadeFFT::process_fifo 1\n");
232 // Load next input buffer
233 if(input_size + size > input_allocation)
235 double *new_input = new double[input_size + size];
236 //printf("CrossfadeFFT::process_fifo 1\n");
239 memcpy(new_input, input_buffer, sizeof(double) * input_size);
240 delete [] input_buffer;
242 //printf("CrossfadeFFT::process_fifo 1\n");
243 input_buffer = new_input;
244 input_allocation = input_size + size;
245 //printf("CrossfadeFFT::process_fifo 1\n");
248 //printf("CrossfadeFFT::process_fifo 1\n");
249 memcpy(input_buffer + input_size,
251 size * sizeof(double));
252 //printf("CrossfadeFFT::process_fifo 1\n");
255 //printf("CrossfadeFFT::process_fifo 1\n");
262 // Have enough to do some windows
263 while(input_size >= window_size)
265 if(!freq_real) freq_real = new double[window_size];
266 if(!freq_imag) freq_imag = new double[window_size];
267 if(!temp_real) temp_real = new double[window_size];
268 if(!temp_imag) temp_imag = new double[window_size];
272 do_fft(window_size, // must be a power of 2
273 0, // 0 = forward FFT, 1 = inverse
274 input_buffer, // array of input's real samples
275 0, // array of input's imag samples
276 freq_real, // array of output's reals
279 int result = signal_process();
283 do_fft(window_size, // must be a power of 2
284 1, // 0 = forward FFT, 1 = inverse
285 freq_real, // array of input's real samples
286 freq_imag, // array of input's imag samples
287 temp_real, // array of output's reals
292 // Crossfade into the output buffer
293 long new_allocation = output_size + window_size;
294 if(new_allocation > output_allocation)
296 double *new_output = new double[new_allocation];
300 memcpy(new_output, output_buffer, sizeof(double) * output_size);
301 //printf("CrossfadeFFT::process_fifo 1 %p\n", output_buffer);
302 delete [] output_buffer;
303 //printf("CrossfadeFFT::process_fifo 2\n");
305 output_buffer = new_output;
306 output_allocation = new_allocation;
309 if(output_size >= WINDOW_BORDER)
311 for(int i = 0, j = output_size - WINDOW_BORDER;
315 double src_level = (double)i / WINDOW_BORDER;
316 double dst_level = (double)(WINDOW_BORDER - i) / WINDOW_BORDER;
317 output_buffer[j] = output_buffer[j] * dst_level + temp_real[i] * src_level;
320 memcpy(output_buffer + output_size,
321 temp_real + WINDOW_BORDER,
322 sizeof(double) * (window_size - WINDOW_BORDER));
323 output_size += window_size - WINDOW_BORDER;
327 // First buffer has no crossfade
328 memcpy(output_buffer + output_size,
330 sizeof(double) * window_size);
331 output_size += window_size;
335 // Shift input buffer forward
336 for(int i = window_size - WINDOW_BORDER, j = 0;
339 input_buffer[j] = input_buffer[i];
340 input_size -= window_size - WINDOW_BORDER;
344 //printf("CrossfadeFFT::process_fifo 1\n");
346 //printf("CrossfadeFFT::process_fifo 1 %d %d\n", output_size - WINDOW_BORDER, size);
349 // Have enough to send to output
350 int samples_rendered = 0;
351 if(output_size - WINDOW_BORDER >= size)
353 memcpy(output_ptr, output_buffer, sizeof(double) * size);
354 for(int i = size, j = 0; i < output_size; i++, j++)
355 output_buffer[j] = output_buffer[i];
357 samples_rendered = size;
361 bzero(output_ptr, sizeof(double) * size);
363 //printf("CrossfadeFFT::process_fifo 2\n");
365 return samples_rendered;