00001 #include <math.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004
00005 #include "clip.h"
00006 #include "fourier.h"
00007 #include "transportque.inc"
00008
00009 #define HALF_WINDOW (window_size / 2)
00010
00011
00012
00013 fftw_plan_desc *FFT::fftw_plans = 0;
00014 Mutex FFT::plans_lock = Mutex();
00015
00016 FFT::FFT()
00017 {
00018 }
00019
00020 FFT::~FFT()
00021 {
00022 }
00023
00024 int FFT::do_fft(unsigned int samples,
00025 int inverse,
00026 double *real_in,
00027 double *imag_in,
00028 double *real_out,
00029 double *imag_out)
00030 {
00031 unsigned int num_bits;
00032 unsigned int i, j, k, n;
00033 unsigned int block_size, block_end;
00034
00035 double angle_numerator = 2.0 * M_PI;
00036 double tr, ti;
00037
00038 if(inverse)
00039 angle_numerator = -angle_numerator;
00040
00041 num_bits = samples_to_bits(samples);
00042
00043
00044
00045 for(i = 0; i < samples; i++)
00046 {
00047 j = reverse_bits(i, num_bits);
00048 real_out[j] = real_in[i];
00049 imag_out[j] = (imag_in == 0) ? 0.0 : imag_in[i];
00050 }
00051
00052
00053
00054 block_end = 1;
00055 double delta_angle;
00056 double sm2;
00057 double sm1;
00058 double cm2;
00059 double cm1;
00060 double w;
00061 double ar[3], ai[3];
00062 double temp;
00063 for(block_size = 2; block_size <= samples; block_size <<= 1)
00064 {
00065 delta_angle = angle_numerator / (double)block_size;
00066 sm2 = sin(-2 * delta_angle);
00067 sm1 = sin(-delta_angle);
00068 cm2 = cos(-2 * delta_angle);
00069 cm1 = cos(-delta_angle);
00070 w = 2 * cm1;
00071
00072 for(i = 0; i < samples; i += block_size)
00073 {
00074 ar[2] = cm2;
00075 ar[1] = cm1;
00076
00077 ai[2] = sm2;
00078 ai[1] = sm1;
00079
00080 for(j = i, n = 0; n < block_end; j++, n++)
00081 {
00082 ar[0] = w * ar[1] - ar[2];
00083 ar[2] = ar[1];
00084 ar[1] = ar[0];
00085
00086 ai[0] = w * ai[1] - ai[2];
00087 ai[2] = ai[1];
00088 ai[1] = ai[0];
00089
00090 k = j + block_end;
00091 tr = ar[0] * real_out[k] - ai[0] * imag_out[k];
00092 ti = ar[0] * imag_out[k] + ai[0] * real_out[k];
00093
00094 real_out[k] = real_out[j] - tr;
00095 imag_out[k] = imag_out[j] - ti;
00096
00097 real_out[j] += tr;
00098 imag_out[j] += ti;
00099 }
00100 }
00101
00102 block_end = block_size;
00103 }
00104
00105
00106
00107 if(inverse)
00108 {
00109 double denom = (double)samples;
00110
00111 for (i = 0; i < samples; i++)
00112 {
00113 real_out[i] /= denom;
00114 imag_out[i] /= denom;
00115 }
00116 }
00117 return 0;
00118 }
00119
00120 int FFT::update_progress(int current_position)
00121 {
00122 return 0;
00123 }
00124
00125 unsigned int FFT::samples_to_bits(unsigned int samples)
00126 {
00127 unsigned int i;
00128
00129 for(i = 0; ; i++)
00130 {
00131 if(samples & (1 << i))
00132 return i;
00133 }
00134 return i;
00135 }
00136
00137 unsigned int FFT::reverse_bits(unsigned int index, unsigned int bits)
00138 {
00139 unsigned int i, rev;
00140
00141 for(i = rev = 0; i < bits; i++)
00142 {
00143 rev = (rev << 1) | (index & 1);
00144 index >>= 1;
00145 }
00146
00147 return rev;
00148 }
00149
00150 int FFT::symmetry(int size, double *freq_real, double *freq_imag)
00151 {
00152 int h = size / 2;
00153 for(int i = h + 1; i < size; i++)
00154 {
00155 freq_real[i] = freq_real[size - i];
00156 freq_imag[i] = -freq_imag[size - i];
00157 }
00158 return 0;
00159 }
00160
00161
00162 int FFT::ready_fftw(unsigned int samples)
00163 {
00164
00165 FFT::plans_lock.lock();
00166 fftw_plan_desc *plan;
00167
00168 my_fftw_plan = 0;
00169
00170 for (plan = fftw_plans; plan; plan = plan->next)
00171 if (plan->samples == samples)
00172 {
00173 my_fftw_plan = plan;
00174 break;
00175 }
00176
00177 if (!my_fftw_plan)
00178 {
00179 fftw_complex *temp_data = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * samples);
00180 my_fftw_plan = new fftw_plan_desc;
00181 my_fftw_plan->samples = samples;
00182 my_fftw_plan->plan_forward = fftw_plan_dft_1d(samples, temp_data, temp_data, FFTW_FORWARD, FFTW_ESTIMATE);
00183 my_fftw_plan->plan_backward = fftw_plan_dft_1d(samples, temp_data, temp_data, FFTW_BACKWARD, FFTW_ESTIMATE);
00184
00185 fftw_free(temp_data);
00186
00187
00188 my_fftw_plan->next = fftw_plans;
00189 fftw_plans = my_fftw_plan;
00190 }
00191
00192 FFT::plans_lock.unlock();
00193 return 0;
00194 }
00195
00196 int FFT::do_fftw_inplace(unsigned int samples,
00197 int inverse,
00198 fftw_complex *data)
00199 {
00200 if (inverse == 0)
00201 fftw_execute_dft(my_fftw_plan->plan_forward, data, data);
00202 else
00203 fftw_execute_dft(my_fftw_plan->plan_backward, data, data);
00204 }
00205
00206
00207
00208
00209 CrossfadeFFT::CrossfadeFFT() : FFT()
00210 {
00211 reset();
00212 window_size = 4096;
00213 }
00214
00215 CrossfadeFFT::~CrossfadeFFT()
00216 {
00217 delete_fft();
00218 }
00219
00220 int CrossfadeFFT::reset()
00221 {
00222 input_buffer = 0;
00223 output_buffer = 0;
00224 freq_real = 0;
00225 freq_imag = 0;
00226 temp_real = 0;
00227 temp_imag = 0;
00228 first_window = 1;
00229
00230 input_size = 0;
00231 output_size = 0;
00232 input_allocation = 0;
00233 output_allocation = 0;
00234 output_sample = 0;
00235 input_sample = 0;
00236 samples_ready = 0;
00237 oversample = 0;
00238 pre_window = 0;
00239 post_window = 0;
00240 fftw_data = 0;
00241 return 0;
00242 }
00243
00244 int CrossfadeFFT::delete_fft()
00245 {
00246 if(input_buffer) delete [] input_buffer;
00247 if(output_buffer) delete [] output_buffer;
00248 if(freq_real) delete [] freq_real;
00249 if(freq_imag) delete [] freq_imag;
00250 if(temp_real) delete [] temp_real;
00251 if(temp_imag) delete [] temp_imag;
00252 if(pre_window) delete [] pre_window;
00253 if(post_window) delete [] post_window;
00254 if(fftw_data) fftw_free(fftw_data);
00255 reset();
00256 return 0;
00257 }
00258
00259 int CrossfadeFFT::fix_window_size()
00260 {
00261
00262
00263 int new_size = 16;
00264 while(new_size < window_size) new_size *= 2;
00265 window_size = MIN(131072, window_size);
00266 window_size = new_size;
00267 return 0;
00268 }
00269
00270 int CrossfadeFFT::initialize(int window_size)
00271 {
00272 this->window_size = window_size;
00273 first_window = 1;
00274 reconfigure();
00275 return 0;
00276 }
00277
00278 long CrossfadeFFT::get_delay()
00279 {
00280 return window_size + HALF_WINDOW;
00281 }
00282
00283 int CrossfadeFFT::reconfigure()
00284 {
00285 delete_fft();
00286 fix_window_size();
00287
00288
00289
00290 return 0;
00291 }
00292
00293
00294
00295 int CrossfadeFFT::process_buffer(int64_t output_sample,
00296 long size,
00297 double *output_ptr,
00298 int direction)
00299 {
00300 int result = 0;
00301 int step = (direction == PLAY_FORWARD) ? 1 : -1;
00302
00303 if(output_sample != this->output_sample || first_window)
00304 {
00305 output_size = 0;
00306 input_size = 0;
00307 first_window = 1;
00308 this->output_sample = output_sample;
00309 this->input_sample = output_sample;
00310 }
00311
00312
00313 while(output_size < size)
00314 {
00315 if(!input_buffer) input_buffer = new double[window_size];
00316 if(!freq_real) freq_real = new double[window_size];
00317 if(!freq_imag) freq_imag = new double[window_size];
00318 if(!temp_real) temp_real = new double[window_size];
00319 if(!temp_imag) temp_imag = new double[window_size];
00320
00321
00322 if(first_window)
00323 result = read_samples(this->input_sample,
00324 window_size,
00325 input_buffer);
00326 else
00327 result = read_samples(this->input_sample + step * HALF_WINDOW,
00328 HALF_WINDOW,
00329 input_buffer + HALF_WINDOW);
00330
00331 input_size = window_size;
00332
00333 if(!result)
00334 do_fft(window_size,
00335 0,
00336 input_buffer,
00337 0,
00338 freq_real,
00339 freq_imag);
00340 if(!result)
00341 result = signal_process();
00342 if(!result)
00343 do_fft(window_size,
00344 1,
00345 freq_real,
00346 freq_imag,
00347 temp_real,
00348 temp_imag);
00349
00350
00351 int new_allocation = output_size + window_size;
00352 if(new_allocation > output_allocation)
00353 {
00354 double *new_output = new double[new_allocation];
00355 if(output_buffer)
00356 {
00357 memcpy(new_output,
00358 output_buffer,
00359 sizeof(double) * (output_size + HALF_WINDOW));
00360 delete [] output_buffer;
00361 }
00362 output_buffer = new_output;
00363 output_allocation = new_allocation;
00364 }
00365
00366
00367 if(first_window)
00368 {
00369 memcpy(output_buffer + output_size,
00370 temp_real,
00371 sizeof(double) * window_size);
00372 first_window = 0;
00373 }
00374 else
00375 {
00376 for(int i = 0, j = output_size; i < HALF_WINDOW; i++, j++)
00377 {
00378 double src_level = (double)i / HALF_WINDOW;
00379 double dst_level = (double)(HALF_WINDOW - i) / HALF_WINDOW;
00380 output_buffer[j] = output_buffer[j] * dst_level +
00381 temp_real[i] * src_level;
00382 }
00383
00384 memcpy(output_buffer + output_size + HALF_WINDOW,
00385 temp_real + HALF_WINDOW,
00386 sizeof(double) * HALF_WINDOW);
00387 }
00388
00389 output_size += HALF_WINDOW;
00390
00391
00392 for(int i = window_size - HALF_WINDOW, j = 0;
00393 i < input_size;
00394 i++, j++)
00395 {
00396 input_buffer[j] = input_buffer[i];
00397 }
00398 input_size = HALF_WINDOW;
00399 this->input_sample += step * HALF_WINDOW;
00400 }
00401
00402
00403
00404
00405 if(output_ptr)
00406 {
00407 memcpy(output_ptr, output_buffer, sizeof(double) * size);
00408 }
00409 for(int i = 0, j = size; j < output_size + HALF_WINDOW; i++, j++)
00410 output_buffer[i] = output_buffer[j];
00411 this->output_sample += step * size;
00412 this->output_size -= size;
00413
00414 return 0;
00415 }
00416
00417 void CrossfadeFFT::set_oversample(int oversample)
00418 {
00419
00420 int oversample_fix = 2;
00421 while(oversample_fix < oversample) oversample_fix *= 2;
00422 this->oversample = oversample = oversample_fix;
00423
00424
00425 pre_window = new double[window_size];
00426 for (int i = 0; i< window_size; i++)
00427 pre_window[i] = 0.5 - 0.5 *cos(2 * M_PI * i / window_size);
00428
00429
00430 post_window = new double[window_size];
00431
00432
00433
00434
00435
00436 for (int i = 0; i< window_size; i++)
00437 post_window[i] = (0.5 - 0.5 *cos(2 * M_PI * i / window_size)) * 6/ oversample / window_size;
00438
00439 ready_fftw(window_size);
00440
00441 }
00442
00443 void smbFft(double *fftBuffer, long fftFrameSize, long sign);
00444
00445
00446
00447
00448 int CrossfadeFFT::process_buffer_oversample(int64_t output_sample,
00449 long size,
00450 double *output_ptr,
00451 int direction)
00452 {
00453 if (oversample <= 0)
00454 {
00455 printf("set_oversample() has to be called to use process_buffer_oversample\n");
00456 return 1;
00457 }
00458 int result = 0;
00459 int step = (direction == PLAY_FORWARD) ? 1 : -1;
00460
00461 int overlap_size = window_size / oversample;
00462 int total_size;
00463 int start_skip;
00464
00465 if (!output_ptr)
00466 {
00467 printf("ERROR, no output pointer!\n");
00468 return 1;
00469 }
00470 if(output_sample != this->output_sample || first_window)
00471 {
00472 input_size = 0;
00473 first_window = 1;
00474 this->output_sample = output_sample;
00475 samples_ready = 0;
00476 start_skip = window_size - overlap_size;
00477 total_size = size + start_skip;
00478
00479 this->input_sample = output_sample - step * start_skip;
00480 if (step == -1) this->input_sample += overlap_size;
00481 } else
00482 {
00483 start_skip = 0;
00484 total_size = size;
00485 first_window = 0;
00486 }
00487
00488
00489 int new_allocation = total_size + window_size;
00490 if(new_allocation > output_allocation)
00491 {
00492 double *new_output = new double[new_allocation];
00493 if(output_buffer)
00494 {
00495 memcpy(new_output,
00496 output_buffer,
00497 sizeof(double) * (samples_ready + window_size - overlap_size));
00498 delete [] output_buffer;
00499
00500 }
00501 output_buffer = new_output;
00502 output_allocation = new_allocation;
00503 }
00504
00505 while(samples_ready < total_size)
00506 {
00507 if(!input_buffer) input_buffer = new double[window_size];
00508 if(!fftw_data) fftw_data = (fftw_complex *)fftw_malloc(window_size * sizeof(fftw_complex));
00509
00510
00511 int64_t read_start;
00512 int write_pos;
00513 int read_len;
00514
00515 if(first_window)
00516 {
00517 if (step == 1)
00518 read_start = this->input_sample;
00519 else
00520 read_start = this->input_sample - window_size;
00521 write_pos = 0;
00522 read_len = window_size;
00523 } else
00524 {
00525 if (step == 1)
00526 {
00527 read_start = this->input_sample + window_size - overlap_size;
00528 write_pos = window_size - overlap_size;
00529 } else
00530 {
00531 read_start = this->input_sample - window_size;
00532 write_pos = 0;
00533 }
00534 read_len = overlap_size;
00535 }
00536
00537 if (read_start + read_len * step< 0)
00538 {
00539
00540 memset (input_buffer + write_pos, 0, read_len * sizeof(double));
00541 result = 1;
00542 } else
00543 if (read_start < 0)
00544 {
00545
00546 memset (input_buffer + write_pos, 0, - read_start * sizeof(double));
00547 result = read_samples(0,
00548 read_start + read_len,
00549 input_buffer - read_start + write_pos);
00550 } else
00551 {
00552
00553 result = read_samples(read_start,
00554 read_len,
00555 input_buffer + write_pos);
00556 }
00557
00558
00559
00560 for (int i = 0; i< window_size; i++)
00561 {
00562 fftw_data[i][0] = input_buffer[i] * pre_window[i];
00563 fftw_data[i][1] = 0;
00564 }
00565
00566
00567 if(!result)
00568 do_fftw_inplace(window_size, 0, fftw_data);
00569 if(!result)
00570 result = signal_process_oversample(first_window);
00571 if(!result)
00572 do_fftw_inplace(window_size, 1, fftw_data);
00573
00574
00575 if (step == 1)
00576 {
00577 for (int i = 0; i < window_size - overlap_size; i++)
00578 output_buffer[i + samples_ready] += fftw_data[i][0] * post_window[i];
00579 for (int i = window_size - overlap_size; i < window_size; i++)
00580 output_buffer[i + samples_ready] = fftw_data[i][0] * post_window[i];
00581 } else
00582 {
00583 int offset = output_allocation - samples_ready - window_size;
00584 for (int i = 0; i < overlap_size; i++)
00585 output_buffer[i + offset] = fftw_data[i][0] * post_window[i];
00586 for (int i = overlap_size; i < window_size; i++)
00587 output_buffer[i + offset] += fftw_data[i][0] * post_window[i];
00588 }
00589
00590
00591
00592 if (step == 1)
00593 memmove(input_buffer, input_buffer + overlap_size, (window_size - overlap_size) * sizeof(double));
00594 else
00595 memmove(input_buffer + overlap_size, input_buffer, (window_size - overlap_size) * sizeof(double));
00596
00597 this->input_sample += step * overlap_size;
00598
00599 samples_ready += overlap_size;
00600 first_window = 0;
00601 }
00602
00603 if (step == 1)
00604 {
00605 memcpy(output_ptr, output_buffer + start_skip , size * sizeof(double));
00606 samples_ready -= total_size;
00607
00608 memmove(output_buffer,
00609 output_buffer + total_size,
00610 (samples_ready + window_size - overlap_size) * sizeof(double));
00611 this->output_sample += size;
00612
00613 } else
00614 {
00615 memcpy(output_ptr, output_buffer + output_allocation - total_size , size * sizeof(double));
00616 samples_ready -= total_size;
00617
00618 memmove(output_buffer + output_allocation - (samples_ready + window_size - overlap_size),
00619 output_buffer + output_allocation - (samples_ready + window_size - overlap_size) - total_size,
00620 (samples_ready + window_size - overlap_size) * sizeof(double));
00621
00622 this->output_sample -= size;
00623 }
00624
00625
00626 return 0;
00627 }
00628
00629
00630 int CrossfadeFFT::read_samples(int64_t output_sample,
00631 int samples,
00632 double *buffer)
00633 {
00634 return 1;
00635 }
00636
00637 int CrossfadeFFT::signal_process()
00638 {
00639 return 0;
00640 }
00641
00642 int CrossfadeFFT::signal_process_oversample(int reset)
00643 {
00644 return 0;
00645 }