X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Ffourier.C;fp=cinelerra-5.0%2Fcinelerra%2Ffourier.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=7f93e5d688447ac16383e9e254f64cbd9b53a5c0;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/fourier.C b/cinelerra-5.0/cinelerra/fourier.C deleted file mode 100644 index 7f93e5d6..00000000 --- a/cinelerra-5.0/cinelerra/fourier.C +++ /dev/null @@ -1,648 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 1997-2011 Adam Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include - -#include "clip.h" -#include "fourier.h" -#include "samples.h" -#include "transportque.inc" - -#define HALF_WINDOW (window_size / 2) - - -FFT::FFT() -{ -} - -FFT::~FFT() -{ -} - -void FFT::bit_reverse(unsigned int samples, - double *real_in, double *imag_in, - double *real_out, double *imag_out) -{ - unsigned int i, j; - unsigned int num_bits = samples_to_bits(samples); - unsigned int samples1 = samples - 1; - if( !real_out ) real_out = real_in; - if( real_out == real_in ) { // Do in-place bit-reversal ordering - if( !imag_in ) { - imag_out[0] = 0.0; - for( i=1; i= j ) continue; - double tr = real_out[j]; - real_out[j] = real_out[i]; real_out[i] = tr; - } - imag_out[samples1] = 0.0; - } - else { - for( i=1; i= j ) continue; - double tr = real_out[j], ti = imag_out[j]; - real_out[j] = real_out[i]; real_out[i] = tr; - imag_out[j] = imag_out[i]; imag_out[i] = ti; - } - } - } - else { // Do simultaneous data copy and bit-reversal ordering - if( !imag_in ) { - real_out[0] = real_in[0]; - imag_out[0] = 0.0; - for( i=0; i j ) continue; - real_out[j] = real_in[i]; - real_out[i] = real_in[j]; - imag_out[i] = imag_out[j] = 0.0; - } - real_out[samples1] = real_in[samples1]; - imag_out[samples1] = 0.0; - } - else { - for( i=0; i j ) continue; - real_out[i] = real_in[j]; imag_out[i] = imag_in[j]; - real_out[j] = real_in[i]; imag_out[j] = imag_in[i]; - } - } - } -} - -int FFT::do_fft(int samples, // must be a power of 2 - int inverse, // 0 = forward FFT, 1 = inverse - double *real_in, double *imag_in, // complex input - double *real_out, double *imag_out) // complex output -{ - bit_reverse(samples, real_in, imag_in, real_out, imag_out); - double angle_numerator = !inverse ? 2*M_PI : -2*M_PI ; - double ar[3], ai[3], rj, ij, rk, ik; -// In the first two passes, all of the multiplys, and half the adds -// are saved by unrolling and reducing the x*1,x*0,x+0 operations. - if( samples >= 2 ) { // block 1, delta_angle = pi - for( int i=0; i= 4 ) { // block 2, delta_angle = pi/2 - if( !inverse ) { - for( int i=0; i=0; ) { - ar[0] = w * ar[1] - ar[2]; - ar[2] = ar[1]; ar[1] = ar[0]; - ai[0] = w * ai[1] - ai[2]; - ai[2] = ai[1]; ai[1] = ai[0]; - - double rj = *rjp, ij = *ijp; - double rk = *rkp, ik = *ikp; - double tr = ar[0] * rk - ai[0] * ik; - double ti = ar[0] * ik + ai[0] * rk; - *rjp++ += tr; *ijp++ += ti; - *rkp++ = rj - tr; *ikp++ = ij - ti; - } - } - - bsz = bsz2; - } -// Normalize if inverse transform - if( inverse ) { - double scale = 1./samples; - for( int i=0; i>i) != 0 ) ++i; - return i; -} - -#if 0 -unsigned int FFT::reverse_bits(unsigned int index, unsigned int bits) -{ - unsigned int i, rev; - - for(i = rev = 0; i < bits; i++) { - rev = (rev << 1) | (index & 1); - index >>= 1; - } - - return rev; -} - -#else - -uint8_t FFT::rev_bytes[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -}; - -unsigned int FFT::reverse_bits(unsigned int index, unsigned int bits) -{ - unsigned char b; - union { unsigned int u; uint8_t b[sizeof(u)]; } data; - data.u = index; - if( bits <= 8 ) { - index = rev_bytes[data.b[0]] >> (8-bits); - } - else if( bits <= 16 ) { - b = data.b[0]; data.b[0] = rev_bytes[data.b[1]]; data.b[1] = rev_bytes[b]; - index = data.u >> (16-bits); - } - else { - b = data.b[0]; data.b[0] = rev_bytes[data.b[3]]; data.b[3] = rev_bytes[b]; - b = data.b[1]; data.b[1] = rev_bytes[data.b[2]]; data.b[2] = rev_bytes[b]; - index = data.u >> (32-bits); - } - return index; -} - -#endif - -int FFT::symmetry(int size, double *freq_real, double *freq_imag) -{ - int h = size / 2; - for(int i = h + 1; i < size; i++) - { - freq_real[i] = freq_real[size - i]; - freq_imag[i] = -freq_imag[size - i]; - } - return 0; -} - - - - - -CrossfadeFFT::CrossfadeFFT() : FFT() -{ - reset(); - window_size = 4096; -} - -CrossfadeFFT::~CrossfadeFFT() -{ - delete_fft(); -} - -int CrossfadeFFT::reset() -{ - input_buffer = 0; - output_buffer = 0; - freq_real = 0; - freq_imag = 0; - output_real = 0; - output_imag = 0; - first_window = 1; -// samples in input_buffer and output_buffer - input_size = 0; - output_size = 0; - input_allocation = 0; - output_allocation = 0; - output_sample = 0; - input_sample = 0; - return 0; -} - -int CrossfadeFFT::delete_fft() -{ - if(input_buffer) delete input_buffer; - if(output_buffer) delete [] output_buffer; - if(freq_real) delete [] freq_real; - if(freq_imag) delete [] freq_imag; - if(output_real) delete [] output_real; - if(output_imag) delete [] output_imag; - reset(); - return 0; -} - -int CrossfadeFFT::fix_window_size() -{ -// fix the window size -// window size must be a power of 2 - int new_size = 16; - while(new_size < window_size) new_size *= 2; - window_size = MIN(131072, window_size); - window_size = new_size; - return 0; -} - -int CrossfadeFFT::initialize(int window_size) -{ - this->window_size = window_size; - first_window = 1; - reconfigure(); - return 0; -} - -long CrossfadeFFT::get_delay() -{ - return window_size + HALF_WINDOW; -} - -int CrossfadeFFT::reconfigure() -{ - delete_fft(); - fix_window_size(); - - - - return 0; -} - -// int CrossfadeFFT::process_fifo(long size, -// double *input_ptr, -// double *output_ptr) -// { -// // Load next input buffer -// if(input_size + size > input_allocation) -// { -// double *new_input = new double[input_size + size]; -// if(input_buffer) -// { -// memcpy(new_input, input_buffer, sizeof(double) * input_size); -// delete [] input_buffer; -// } -// input_buffer = new_input; -// input_allocation = input_size + size; -// } -// -// memcpy(input_buffer + input_size, -// input_ptr, -// size * sizeof(double)); -// input_size += size; -// -// -// -// -// -// -// -// // Have enough to do some windows -// while(input_size >= window_size) -// { -// if(!freq_real) freq_real = new double[window_size]; -// if(!freq_imag) freq_imag = new double[window_size]; -// if(!output_real) output_real = new double[window_size]; -// if(!output_imag) output_imag = new double[window_size]; -// -// -// -// do_fft(window_size, // must be a power of 2 -// 0, // 0 = forward FFT, 1 = inverse -// input_buffer, // array of input's real samples -// 0, // array of input's imag samples -// freq_real, // array of output's reals -// freq_imag); -// -// int result = signal_process(); -// -// if(!result) -// { -// do_fft(window_size, // must be a power of 2 -// 1, // 0 = forward FFT, 1 = inverse -// freq_real, // array of input's real samples -// freq_imag, // array of input's imag samples -// output_real, // array of output's reals -// output_imag); -// } -// -// -// // Crossfade into the output buffer -// long new_allocation = output_size + window_size; -// if(new_allocation > output_allocation) -// { -// double *new_output = new double[new_allocation]; -// -// if(output_buffer) -// { -// memcpy(new_output, output_buffer, sizeof(double) * output_size); -// delete [] output_buffer; -// } -// output_buffer = new_output; -// output_allocation = new_allocation; -// } -// -// if(output_size >= HALF_WINDOW) -// { -// for(int i = 0, j = output_size - HALF_WINDOW; -// i < HALF_WINDOW; -// i++, j++) -// { -// double src_level = (double)i / HALF_WINDOW; -// double dst_level = (double)(HALF_WINDOW - i) / HALF_WINDOW; -// output_buffer[j] = output_buffer[j] * dst_level + output_real[i] * src_level; -// } -// -// memcpy(output_buffer + output_size, -// output_real + HALF_WINDOW, -// sizeof(double) * (window_size - HALF_WINDOW)); -// output_size += window_size - HALF_WINDOW; -// } -// else -// { -// // First buffer has no crossfade -// memcpy(output_buffer + output_size, -// output_real, -// sizeof(double) * window_size); -// output_size += window_size; -// } -// -// -// // Shift input buffer forward -// for(int i = window_size - HALF_WINDOW, j = 0; -// i < input_size; -// i++, j++) -// input_buffer[j] = input_buffer[i]; -// input_size -= window_size - HALF_WINDOW; -// } -// -// -// -// -// // Have enough to send to output -// int samples_rendered = 0; -// if(output_size - HALF_WINDOW >= size) -// { -// memcpy(output_ptr, output_buffer, sizeof(double) * size); -// for(int i = size, j = 0; i < output_size; i++, j++) -// output_buffer[j] = output_buffer[i]; -// output_size -= size; -// samples_rendered = size; -// } -// else -// { -// bzero(output_ptr, sizeof(double) * size); -// } -// -// return samples_rendered; -// } - - - -int CrossfadeFFT::process_buffer(int64_t output_sample, - long size, - Samples *output_ptr, - int direction) -{ - int result = 0; - int step = (direction == PLAY_FORWARD) ? 1 : -1; - -// User seeked so output buffer is invalid - if(output_sample != this->output_sample) - { - output_size = 0; - input_size = 0; - first_window = 1; - this->output_sample = output_sample; - this->input_sample = output_sample; - } - -// Fill output buffer half a window at a time until size samples are available - while(output_size < size) - { - if(!input_buffer) input_buffer = new Samples(window_size); - if(!freq_real) freq_real = new double[window_size]; - if(!freq_imag) freq_imag = new double[window_size]; - if(!output_real) output_real = new double[window_size]; - if(!output_imag) output_imag = new double[window_size]; - -// Fill enough input to make a window starting at output_sample - if(first_window) - result = read_samples(this->input_sample, - window_size, - input_buffer); - else - { - input_buffer->set_offset(HALF_WINDOW); -// printf("CrossfadeFFT::process_buffer %d %lld %lld\n", -// __LINE__, -// this->input_sample + step * HALF_WINDOW, -// this->input_sample + step * HALF_WINDOW + HALF_WINDOW); - result = read_samples(this->input_sample + step * HALF_WINDOW, - HALF_WINDOW, - input_buffer); - input_buffer->set_offset(0); - } - - input_size = window_size; - - if(!result) - do_fft(window_size, // must be a power of 2 - 0, // 0 = forward FFT, 1 = inverse - input_buffer->get_data(), // array of input's real samples - 0, // array of input's imag samples - freq_real, // array of output's reals - freq_imag); - if(!result) - result = signal_process(); - - if(!result) - do_fft(window_size, // must be a power of 2 - 1, // 0 = forward FFT, 1 = inverse - freq_real, // array of input's real samples - freq_imag, // array of input's imag samples - output_real, // array of output's reals - output_imag); // array of output's imaginaries - - if(!result) - result = post_process(); - -// Allocate output buffer - int new_allocation = output_size + window_size; - if(new_allocation > output_allocation) - { - double *new_output = new double[new_allocation]; - if(output_buffer) - { - memcpy(new_output, - output_buffer, - sizeof(double) * (output_size + HALF_WINDOW)); - delete [] output_buffer; - } - output_buffer = new_output; - output_allocation = new_allocation; - } - -// Overlay processed buffer - if(first_window) - { - memcpy(output_buffer + output_size, - output_real, - sizeof(double) * window_size); - first_window = 0; - } - else - { - for(int i = 0, j = output_size; i < HALF_WINDOW; i++, j++) - { - double src_level = (double)i / HALF_WINDOW; - double dst_level = (double)(HALF_WINDOW - i) / HALF_WINDOW; - output_buffer[j] = output_buffer[j] * dst_level + - output_real[i] * src_level; - } - -//output_buffer[output_size] = 100.0; -//output_buffer[output_size + HALF_WINDOW] = -100.0; - - memcpy(output_buffer + output_size + HALF_WINDOW, - output_real + HALF_WINDOW, - sizeof(double) * HALF_WINDOW); - } - - - output_size += HALF_WINDOW; - -// Shift input buffer - double *input_samples = input_buffer->get_data(); - for(int i = window_size - HALF_WINDOW, j = 0; - i < input_size; - i++, j++) - { - input_samples[j] = input_samples[i]; - } - - input_size = HALF_WINDOW; - this->input_sample += step * HALF_WINDOW; - } - - - -// Transfer output buffer - if(output_ptr) - { - memcpy(output_ptr->get_data(), output_buffer, sizeof(double) * size); - } - for(int i = 0, j = size; j < output_size + HALF_WINDOW; i++, j++) - output_buffer[i] = output_buffer[j]; - - this->output_sample += step * size; - this->output_size -= size; - - return 0; -} - - -int CrossfadeFFT::read_samples(int64_t output_sample, - int samples, - Samples *buffer) -{ - return 1; -} - -int CrossfadeFFT::signal_process() -{ - return 0; -} - - - -int CrossfadeFFT::post_process() -{ - return 0; -} - - - - - - - -