// Applies the FFT-scale-IFFT algorithm to an input array 
// Also applies window before frequency scaling
void frequencyScale(float *input, float *output, int len, float *scalars)
{
    int i;

    kiss_fft_scalar inputArray[len];
    kiss_fft_cpx transformedArray[len / 2 + 1];

    for (i = 0; i < len; i++)
    {
        //inputComplex[i].r = input[i];
        //inputComplex[i].i = 0;
        inputArray[i] = input[i];
    }

    kiss_fftr(fftr_cfg, inputArray, transformedArray);

    for (i = 0; i < SCALING_SIZE; i++)
    {
        transformedArray[i].r *= scalars[i];
        transformedArray[i].i *= scalars[i];
    }

    kiss_fftri(ifftr_cfg, transformedArray, inputArray);

    for (i = 0; i < ARRAY_SIZE; i++)
    {
        output[i] = inputArray[i] / (1.0 * ARRAY_SIZE);
    }
}
Beispiel #2
0
void sf_cosft_inv (float *q /* data */, 
				   int o1   /* first sample */, 
				   int d1   /* step */) 
/*< inverse transform >*/
{
    int i;
	
	
    for (i=0; i < n1; i++) {
		pp[i].r = q[o1+i*d1];
		pp[i].i = 0.;
    }
    /* pad */
    for (i=n1; i < nw; i++) { 
		pp[i].r = 0.; 
		pp[i].i = 0.;
    }

#ifdef SF_HAS_FFTW   
    fftwf_execute(icfg);
#else
    kiss_fftri(invs,pp,p);
#endif
    
    for (i=0; i < n1; i++) {
		q[o1+i*d1] = p[i]/nt;
    }
}
Beispiel #3
0
void FFT::freq2smp(){
	REALTYPE inv_2p15_2pi=1.0/16384.0*M_PI;
	for (int i=1;i<nsamples/2;i++) {
		rand_seed=(rand_seed*1103515245+12345);
		unsigned int rand=(rand_seed>>16)&0x7fff;
		REALTYPE phase=rand*inv_2p15_2pi;
#ifdef KISSFFT
		datac[i].r=freq[i]*cos(phase);
		datac[i].i=freq[i]*sin(phase);
#else
		data[i]=freq[i]*cos(phase);
		data[nsamples-i]=freq[i]*sin(phase);
#endif
	};

#ifdef KISSFFT
	datac[0].r=datac[0].i=0.0;
	kiss_fftri(plankifft,datac,datar);
	for (int i=0;i<nsamples;i++) smp[i]=datar[i]/nsamples;
#else
	data[0]=data[nsamples/2+1]=data[nsamples/2]=0.0;
	fftwf_execute(planifftw);
	for (int i=0;i<nsamples;i++) smp[i]=data[i]/nsamples;
#endif
};
static
void fft_file_real(FILE * fin, FILE * fout, int nfft, int isinverse)
{
    kiss_fftr_cfg st;
    kiss_fft_scalar * rbuf;
    kiss_fft_cpx * cbuf;

    rbuf = (kiss_fft_scalar*)malloc(sizeof(kiss_fft_scalar) * nfft);
    cbuf = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * (nfft / 2 + 1));
    st = kiss_fftr_alloc(nfft , isinverse , 0, 0);

    if (isinverse == 0) {
        while (fread(rbuf , sizeof(kiss_fft_scalar) * nfft , 1, fin) > 0) {
            kiss_fftr(st , rbuf , cbuf);
            fwrite(cbuf , sizeof(kiss_fft_cpx) , (nfft / 2 + 1) , fout);
        }
    } else {
        while (fread(cbuf , sizeof(kiss_fft_cpx) * (nfft / 2 + 1) , 1, fin) > 0) {
            kiss_fftri(st , cbuf , rbuf);
            fwrite(rbuf , sizeof(kiss_fft_scalar) , nfft , fout);
        }
    }
    free(st);
    free(rbuf);
    free(cbuf);
}
Beispiel #5
0
JNIEXPORT void JNICALL Java_de_jurihock_voicesmith_dsp_KissFFT_ifft
(JNIEnv* env, jobject, jlong handle, jfloatArray _buffer)
{
	KissFFT* fft = (KissFFT*)handle;

	float* buffer = (float*)env->GetPrimitiveArrayCritical(_buffer, 0);

	// buffer => spectrum
	memcpy(fft->spectrum, buffer, sizeof(float)*fft->size);

	// Im(DC) => Re(Nyquist)
	fft->spectrum[fft->size/2].r = fft->spectrum[0].i;
	fft->spectrum[0].i = 0;
	fft->spectrum[fft->size/2].i = 0;

	// ifft(spectrum) => buffer
	kiss_fftri(fft->backward, fft->spectrum, buffer);

	// Normalize buffer values by 1/N
	for (int i = 0; i < fft->size; i++)
	buffer[i] /= fft->size;

	// Circular shift by N/2
	fftshift(fft, buffer);

	env->ReleasePrimitiveArrayCritical(_buffer, buffer, 0);
}
Beispiel #6
0
void ifft3(float *out      /* [n1*n2*n3] */, 
	   sf_complex *inp /* [nk*n2*n3] */)
/*< 3-D inverse FFT >*/
{
    int i1, i2, i3;

#ifdef SF_HAS_FFTW
    fftwf_execute(icfg);
#else

    /* IFFT over third axis */
    for (i2=0; i2 < n2; i2++) {
	for (i1=0; i1 < nk; i1++) {
	    kiss_fft_stride(icfg3,(kiss_fft_cpx *) (inp+i2*nk+i1),ctrace3,nk*n2);
	    for (i3=0; i3<n3; i3++) {
		tmp[i3][i2][i1] = ctrace3[i3];
	    }
	}
    }
    
    /* IFFT over second axis */
    for (i3=0; i3 < n3; i3++) {
	for (i1=0; i1 < nk; i1++) {
	    kiss_fft_stride(icfg2,tmp[i3][0]+i1,ctrace2,nk);		
	    for (i2=0; i2<n2; i2++) {
		tmp[i3][i2][i1] = ctrace2[i2];
	    }
	}
    }

    /* IFFT over first axis */
    for (i3=0; i3 < n3; i3++) {
	for (i2=0; i2 < n2; i2++) {
	    if (cmplx) {
		kiss_fft_stride(icfg1,tmp[i3][i2],(kiss_fft_cpx *) cc[i3][i2],1);		
	    } else {
		kiss_fftri(icfg,tmp[i3][i2],ff[i3][i2]);
	    }
	}
    }

#endif

    /* FFT centering and normalization */
    for (i3=0; i3<n3; i3++) {
	for (i2=0; i2<n2; i2++) {
	    for (i1=0; i1<n1; i1++) {
		if (cmplx) {
		    out[(i3*n2+i2)*n1+i1] = ((((i3%2==0)==(i2%2==0))==(i1%2==0))? wt:-wt)*crealf(cc[i3][i2][i1]);
		} else {
		    out[(i3*n2+i2)*n1+i1] = (((i3%2==0)==(i2%2==0))? wt: - wt)*ff[i3][i2][i1];
		}
	    }
	}
    }
}
Beispiel #7
0
double stdAutoCorr(const kiss_fft_scalar *input, float *output, unsigned long const tSize, unsigned long const pBiscN, unsigned long const tK)
{
    unsigned long const SizeOver2 = tSize/2;

    {for (unsigned long i = 0; i < pBiscN; ++i) //###Slow: but: I need to copy 2048 input elements into 3072 buf
#ifdef FIXED_POINT
        aR2HCI[i] = input[i] * 32768;
#else
        aR2HCI[i] = input[i] / 32768.0f;
#endif
    }

    //Do a forward FFT
    kiss_fftr(cfgR2HC, &aR2HCI[0], &*aR2HCO.begin());

    //calculate the (real*real + ima*imag) for each coefficient
    {for(unsigned int j=1; j<SizeOver2; j++) 
    {
#ifdef FIXED_POINT
        aHC2RI[j].r = ((((__int64)aR2HCO[j].r) * ((__int64)aR2HCO[j].r)) / maxrange) + ((((__int64)aR2HCO[j].i) * ((__int64)aR2HCO[j].i)) / maxrange);
#else
        aHC2RI[j].r = sq(aR2HCO[j].r) + sq(aR2HCO[j].i); //Imag part already zero..
#endif
    }}

    //Square the 1st real element, and the last
#ifdef FIXED_POINT
    aHC2RI[0].r = (maxrangeSHIFT1)*sq(aR2HCO[0].r/ (float)maxrange); //!!!Can probably speed up a tiny bit more by removing FP maths here
    aHC2RI[SizeOver2].r = (maxrangeSHIFT1)*sq(aR2HCO[SizeOver2].r/ (float)maxrange);
#else
    aHC2RI[0].r = sq(aR2HCO[0].r);
    aHC2RI[SizeOver2].r = sq(aR2HCO[SizeOver2].r);
#endif

    //Do an inverse FFT
    kiss_fftri(cfgHC2R, &*aHC2RI.begin(), &*aHC2RO.begin());

    //extract the wanted elements out, and normalise
    float * p1 = 0; kiss_fft_scalar *p2 = 0;
    {for(p1=output, p2=(&*aHC2RO.begin())+1; p1<output+tK;)
    {
        //###Will this be better if I divide the int by 64 then make a fload? Or will i lose too much precision
#ifdef FIXED_POINT
        *p1++ = ((float)*p2++) / 64; //Magic number: began with * 54 or so from s_tmpdMax comparison with float, and then wound down to /= until it worked.
#else
        *p1++ = ((float)*p2++) / tSize;
#endif
    }}

#ifdef FIXED_POINT
    return ((float)aHC2RO[0]) / 64;
#else
    return ((float)aHC2RO[0]) / tSize;
#endif
}
Beispiel #8
0
/**
 * Run the actual transform based on the parameters set up in the
 * constructor.
 */
void Tracter::Fourier::Transform()
{
    assert(mFourierData);
    FourierData& m = *mFourierData;

    switch (m.Type)
    {
    case DCT2:
    {
        /* Duplicate */
        float* idata = (float*)m.IData;
        for (int i=0; i<m.Order; i++)
        {
            /* [1 2 3] -> [1 2 3 3 2 1] */
            idata[i+m.Order] = idata[m.Order-1-i];
        }

        /* Transform and rotate */
        kiss_fftr((kiss_fftr_cfg)m.Config, (const float*)m.IData, m.TmpData);
        float* odata = (float*)m.OData;
        for (int i=0; i<m.Order; i++)
        {
            float theta = 2.0f*M_PI*(-0.5f)*i/(2.0f*m.Order);
            odata[i] = ( m.TmpData[i].r * cos(theta) -
                         m.TmpData[i].i * sin(theta) );
        }
        break;
    }

    case REAL_TO_COMPLEX:
        kiss_fftr(
            (kiss_fftr_cfg)m.Config,
            (const float*)m.IData, (kiss_fft_cpx*)m.OData
        );
        break;

    case COMPLEX_TO_REAL:
        kiss_fftri(
            (kiss_fftr_cfg)m.Config,
            (const kiss_fft_cpx*)m.IData, (float*)m.OData
        );
        break;

    case COMPLEX_TO_COMPLEX:
        kiss_fft(
            (kiss_fft_cfg)m.Config,
            (const kiss_fft_cpx*)m.IData, (kiss_fft_cpx*)m.OData
        );
        break;

    default:
        assert(0);
    }
}
Beispiel #9
0
void ifft2(float *out      /* [n1*n2] */, 
	   sf_complex *inp /* [nk*n2] */)
/*< 2-D inverse FFT >*/
{
    int i1, i2;

#ifdef SF_HAS_FFTW
    if (NULL==icfg) {
      icfg = cmplx? 
	fftwf_plan_dft_2d(n2,n1,
			  (fftwf_complex *) dd, 
			  (fftwf_complex *) cc[0],
			  FFTW_BACKWARD, FFTW_MEASURE):
	fftwf_plan_dft_c2r_2d(n2,n1,
			      (fftwf_complex *) dd, ff[0],
			      FFTW_MEASURE);
      if (NULL == icfg) sf_error("FFTW failure.");
    }
#endif

#ifdef SF_HAS_FFTW
    for (i1=0; i1 < nk*n2; i1++)
      dd[i1] = inp[i1];

    fftwf_execute(icfg);
#else
    for (i1=0; i1 < nk; i1++) {
	kiss_fft_stride(icfg2,(kiss_fft_cpx *) (inp+i1),ctrace2,nk);
		
	for (i2=0; i2<n2; i2++) {
	    tmp[i2][i1] = ctrace2[i2];
	}
    }
    for (i2=0; i2 < n2; i2++) {
	if (cmplx) {
	    kiss_fft_stride(icfg1,tmp[i2],(kiss_fft_cpx *) cc[i2],1);
	} else {
	    kiss_fftri(icfg,tmp[i2],ff[i2]);
	}
    }
#endif
    
    /* FFT centering and normalization */
    for (i2=0; i2<n2; i2++) {
	for (i1=0; i1<n1; i1++) {
	    if (cmplx) {
		out[i2*n1+i1] = (((i2%2==0)==(i1%2==0))? wt:-wt) * crealf(cc[i2][i1]);
	    } else {
		out[i2*n1+i1] = (i2%2? -wt: wt)*ff[i2][i1];
	    }
	}
    }
}
Beispiel #10
0
void fft1_2D_inv (float *input, float *output, int n2)
/*< Fast Fourier Transform along the first axis >*/
{
    /*bool inv, sym, opt;*/
    int n1, i1, i2;
    float  *p,  wt, shift;
    kiss_fft_cpx *pp, ce;
    char *label;
    sf_file out=NULL;
    kiss_fftr_cfg cfg;
	bool verb;

	verb=1;

    
    
  p = sf_floatalloc(ntopt);
  pp = (kiss_fft_cpx*) sf_complexalloc(nw);

  cfg = kiss_fftr_alloc(ntopt,1,NULL,NULL);
  wt = sym? 1./sqrtf((float) ntopt): 1.0/ntopt;


	for (i2=0; i2 < n2; i2++) {
	    /*sf_floatread((float*) pp,2*nw,in);*/
		  memcpy(pp,&input[i2*2*nw],2*nw*sizeof(float));


		  for (i1=0; i1 < nw; i1++) {
        shift = +2.0*SF_PI*i1*dw*ot;
        ce.r = cosf(shift);
        ce.i = sinf(shift);
		    pp[i1]=sf_cmul(pp[i1],ce);
		  }

	    kiss_fftri(cfg,pp,p);

	    for (i1=0; i1 < ntopt; i1++) {
		    p[i1] *= wt;
	    }

		  memcpy(&output[i2*nt],p,nt*sizeof(float));
  }

	free(p);
	free(pp);

    
	/*exit (0);*/
}
Beispiel #11
0
void HrtfData::linearPhase(float* buffer) {
    //Note that this is in effect circular convolution with a truncation.
    std::copy(buffer, buffer+hrir_length, fft_time_data);
    std::fill(fft_time_data+hrir_length, fft_time_data+hrir_length*2, 0.0f);
    kiss_fftr(fft, fft_time_data, fft_data);
    for(int i = 0; i < hrir_length+1; i++) {
        fft_data[i].r = cabs(fft_data[i].r, fft_data[i].i);
        fft_data[i].i = 0.0f;
    }
    kiss_fftri(ifft, fft_data, fft_time_data);
    //Apply the downscaling that kissfft requires, otherwise this is too loud.
    //Also accomplish copying back to the starting piont.
    scalarMultiplicationKernel(hrir_length, 1.0f/(2*hrir_length), fft_time_data, buffer);
}
Beispiel #12
0
void FFT_Transform( FFT* fft )
{
    switch( fft->direction )
    {
        case FORWARD:
            kiss_fftr(fft->config,fft->realSignal,fft->spectrum);
            scale(fft);
            break;
        case INVERSE:
            kiss_fftri(fft->config,fft->spectrum,fft->realSignal);
            scale(fft);
            break;
    }
}
Beispiel #13
0
void
fft_filt_c::work_real() {
 for (uint32_t i=0;i<fft_len;i++) {
  input_buf_r[i] = (i<l) ? (*in)[i] * fft_len : 0;
 };

 kiss_fftr(fft_fcfg_r, input_buf_r, fdom_buf);

 // for (uint32_t i=0;i<fft_len/2+1;i++) { d3(i,fdom_buf[i].r,fdom_buf[i].i); }
  
 // now we convolve with the filter. 
 // This should be fraction * fraction = fraction... one would hope
 const bool test_mode = false;
 if (test_mode) {
  for (uint32_t i=0;i<fft_len/2+1;i++) {
    fdom_buf[i].i *= 1;
    fdom_buf[i].r *= 1;
  }
 } else {
  for (uint32_t i=0;i<(fft_len/2+1);i++) {
   int64_t i_i = fdom_buf[i].i;
   int64_t i_r = fdom_buf[i].r;
   int64_t f_i = filt_buf[i].i;
   int64_t f_r = filt_buf[i].r; 
   int64_t p_r = (i_r * f_r - i_i * f_i);
   int64_t p_i = (i_r * f_i + i_i * f_r);
   fdom_conv_buf[i].i = p_i >> 15;
   fdom_conv_buf[i].r = p_r >> 15;
  }
 }

 // for (uint32_t i=0;i<fft_len/2+1;i++) { d7c(i,filt_buf[i].r,filt_buf[i].i, fdom_buf[i].r,fdom_buf[i].i, fdom_conv_buf[i].r, fdom_conv_buf[i].i); };

 kiss_fftri(fft_icfg_r,fdom_conv_buf,output_buf_r);

 // for (uint32_t i=0;i<fft_len/2+1;i++) { d3c(i,(*in)[i],output_buf_r[i]); };

 uint32_t extra = fft_len - l;
 for (uint32_t i=0; i<l; i++) {
  int32_t vr = output_buf_r[i];
  vr += (i<extra) ? last_output_buf_r[i] : 0;
  (*out)[i]   = vr;
 }

 for (uint32_t i=0;i<extra;i++) {
  last_output_buf_r[i] = output_buf_r[i+l];
 }
};
void FftConvolver::convolveFft(kiss_fft_cpx *fft, float* output) {
	//Do a complex multiply.
	//Note that the first line is subtraction because of the i^2.
	for(int i=0; i < fft_size; i++) {
		kiss_fft_cpx tmp;
		tmp.r = fft[i].r*response_fft[i].r-fft[i].i*response_fft[i].i;
		tmp.i = fft[i].r*response_fft[i].i+fft[i].i*response_fft[i].r;
		block_fft[i] = tmp;
	}
	kiss_fftri(ifft, block_fft, workspace);
	//Add the tail over the block.
	additionKernel(tail_size, tail, workspace, workspace);
	//Downscale the first part, our output.
	//Also copy to the output at the same time.
	scalarMultiplicationKernel(block_size, 1.0/workspace_size, workspace, output);
	//Copy out the tail.
	std::copy(workspace+block_size, workspace+workspace_size, tail);
}
Beispiel #15
0
void IFFT::transform (std::complex<ssi_real_t> *src, 
	ssi_real_t *dst) {

	for (ssi_size_t j = 0; j < dim; j++) {
		kiss_fft_cpx *fptr = _fdata[j];
		std::complex<ssi_real_t> *srcptr = src + j;
		for (ssi_size_t i = 0; i < rfft; i++) {
			(*fptr).r = (*srcptr).real ();
			(*fptr).i = (*srcptr).imag ();
			srcptr += dim;
			fptr++;
		}
		kiss_fftri (_icfg, _fdata[j], _data[j]);
	}
			
	for (ssi_size_t i = 0; i < nfft; i++) {
		for (ssi_size_t j = 0; j < dim; j++) {
			*dst++ = _data[j][i] / nfft;
		}
	}


}
Beispiel #16
0
void dm_fftSetupExecute(dm_fftSetup fftSetup_, unsigned long timeDomainLength_, float* timeDomain_, dm_fftComplexArrayT*  frequency_, unsigned long offset_) {
  fftsetup_internal* setup = (fftsetup_internal*)fftSetup_;
#ifdef DSP_USE_ACCELERATE
  if (setup->direction == DM_FFT_FORWARD) {
    frequency_->fillFromVector(timeDomain_, timeDomainLength_/2);
    vDSP_fft_zrip(setup->fftSetup, (DSPSplitComplex*)frequency_, 1, setup->logFftSize, FFT_FORWARD);
  } else {
    vDSP_fft_zrip(setup->fftSetup, (DSPSplitComplex*)frequency_, 1, setup->logFftSize, FFT_INVERSE);
    frequency_->toRealVector(timeDomain_, offset_, timeDomainLength_);
  }
#else
  
  if (setup->direction == DM_FFT_FORWARD) {
    memcpy(setup->temp, timeDomain_, sizeof(float) * timeDomainLength_);
    kiss_fftr(setup->fftSetup, (const kiss_fft_scalar *)setup->temp, (kiss_fft_cpx*)frequency_->data);
  } else {
    kiss_fftri(setup->fftSetup, (const kiss_fft_cpx*)frequency_->data, (kiss_fft_scalar *)setup->temp);
    memcpy(timeDomain_, setup->temp + offset_ * 2, timeDomainLength_ * sizeof(float));
    dm_vsfill(0, timeDomain_ + timeDomainLength_, frequency_->size());
  }
  
#endif
}
Beispiel #17
0
void ifft2(float *out      /* [n1*n2] */,
           sf_complex *inp /* [nk*n2] */)
/*< 2-D inverse FFT >*/
{
    int i1, i2;

#ifdef SF_HAS_FFTW
    fftwf_execute(icfg);
#else
    for (i1=0; i1 < nk; i1++) {
        kiss_fft_stride(icfg2,(kiss_fft_cpx *) (inp+i1),ctrace2,nk);

        for (i2=0; i2<n2; i2++) {
            tmp[i2][i1] = ctrace2[i2];
        }
    }
    for (i2=0; i2 < n2; i2++) {
        if (cmplx) {
            kiss_fft_stride(icfg1,tmp[i2],(kiss_fft_cpx *) cc[i2],1);
        } else {
            kiss_fftri(icfg,tmp[i2],ff[i2]);
        }
    }
#endif

    /* FFT centering and normalization */
    for (i2=0; i2<n2; i2++) {
        for (i1=0; i1<n1; i1++) {
            if (cmplx) {
                out[i2*n1+i1] = (((i2%2==0)==(i1%2==0))? wt:-wt) * crealf(cc[i2][i1]);
            } else {
                out[i2*n1+i1] = (i2%2? -wt: wt)*ff[i2][i1];
            }
        }
    }
}
Beispiel #18
0
int main(int argc, char* argv[])
{
    int verbose;
    sf_file in=NULL, out=NULL;
    int n1_traces;
    int n1_headers;

    char* header_format=NULL;
    sf_datatype typehead;
    /* kls do I need to add this?  sf_datatype typein; */
    float* fheader=NULL;
    float* intrace=NULL;
    float* outtrace=NULL;
    float* bandlimittrace=NULL;
    float* rmsall=NULL;
    float* rmsband=NULL;
    float* scalars=NULL;
    float* sum_of_scalars=NULL;
    int indx_time;
    int itrace=0;
    int ntaper;
    int numxstart;
    int numtstart;
    float* taper;
    char **list_of_floats;
    float* xstart;
    float* tstart;
    int indx_of_offset;
    float offset;
    float d1;
    float o1;
    float time_start;
    int itime_start;
    int itime_stop;
    int indx_taper;
    float wagc;
    int lenagc;

    float fmin=5;
    float fmax=95;
    float finc=5;
    int num_centerfreq;
    int firstlive;
    int lastlive;
    float pnoise;

    kiss_fftr_cfg cfg,icfg;
    sf_complex *fft1;
    sf_complex *fft2;
    int nfft;
    int nf;
    float df;
    float scale;
    int ifreq;
    float cntrfreq;
    
    /*****************************/
    /* initialize verbose switch */
    /*****************************/
    sf_init (argc,argv);

    if(!sf_getint("verbose",&verbose))verbose=1;
    /* \n
       flag to control amount of print
       0 terse, 1 informative, 2 chatty, 3 debug
    */
    sf_warning("verbose=%d",verbose);
 
    /******************************************/
    /* input and output data are stdin/stdout */
    /******************************************/

    if(verbose>0)fprintf(stderr,"read in file name\n");  
    in = sf_input ("in");

    if(verbose>0)fprintf(stderr,"read out file name\n");
    out = sf_output ("out");

    if (!sf_histint(in,"n1_traces",&n1_traces))
	sf_error("input data not define n1_traces");
    if (!sf_histint(in,"n1_headers",&n1_headers)) 
	sf_error("input data does not define n1_headers");

    header_format=sf_histstring(in,"header_format");
    if(strcmp (header_format,"native_int")==0) typehead=SF_INT;
    else                                       typehead=SF_FLOAT;

    if(verbose>0)fprintf(stderr,"allocate headers.  n1_headers=%d\n",n1_headers);
    fheader = sf_floatalloc(n1_headers);
 
    /*  allocate intrace and outtrace after initialize fft and 
	make them padded */
  
    /* maybe I should add some validation that n1== n1_traces+n1_headers+2
       and the record length read in the second word is consistent with 
       n1.  */

    /**********************************************************/
    /* end code block for standard tah Trace And Header setup */
    /* continue with any sf_puthist this tah program calls to */
    /* add to the history file                                */
    /**********************************************************/

    /* put the history from the input file to the output */
    sf_fileflush(out,in);

    /********************************************************/
    /* continue initialization specific to this tah program */
    /********************************************************/





    /* segy_init gets the list header keys required by segykey function  */
    segy_init(n1_headers,in);

    if(0==1) {  
      /* infuture may want to have offset dependent agc design start time */
      /* get the mute parameters */
      if(NULL==(list_of_floats=sf_getnstring("xstart",&numxstart))){
	xstart=NULL;
	sf_error("xstart is a required parameter in sftahagc");
      } else {
	xstart=sf_floatalloc(numxstart);
	if(!sf_getfloats("xstart",xstart,numxstart))sf_error("unable to read xstart");
      }
      if(NULL==(list_of_floats=sf_getnstring("tstart",&numtstart))){
	tstart=NULL;
	sf_error("xstart is a required parameter in sftahagc");
      } else {
	tstart=sf_floatalloc(numtstart);
	if(!sf_getfloats("tstart",tstart,numtstart))sf_error("unable to read tstart");
      }
      if(numxstart!=numtstart)sf_error("bad mute parameters: numxstart!=numtstart");
      if(!sf_getint("ntaper",&ntaper))ntaper=12;
    }
    /* \n
       length of the taper on the stack mute
    */
    /* is this of use for agc?
    taper=sf_floatalloc(ntaper);
    for(indx_time=0; indx_time<ntaper; indx_time++){
	float val_sin=sin((indx_time+1)*SF_PI/(2*ntaper));
	taper[indx_time]=val_sin*val_sin;
    }
    */
    indx_of_offset=segykey("offset");
    
    if (!sf_histfloat(in,"d1",&d1))
      sf_error("input data does not define d1");
    if (!sf_histfloat(in,"o1",&o1))
      sf_error("input data does not define o1");

    /* check wagc for reasonableness.  I input 250 (not .25 and ,250) */  
    if(!sf_getfloat("wagc",&wagc))wagc=-1;
    /* \n
       length of the agc window in seconds
    */
    if(wagc<0)sf_error("wagc is a required parameter in sftahagc");

    lenagc=wagc/d1+1.5; /* length of the agc window in samples */
 
    if (!sf_getfloat("pnoise",  &pnoise)) pnoise = 0.01;
    /* relative additive noise level */
    
    if (!sf_getfloat("fmin",&fmin))fmin=5;
    /* minimum frequency band */
    if (!sf_getfloat("fmax",&fmax))fmax=95;
    /* maximum frequency band */
    if (!sf_getfloat("finc",&finc))finc=5;
    /* frequency band increment */

    /* initialize kiss_fft kls */

    nfft  = kiss_fft_next_fast_size(n1_traces+200);
    nf    = nfft/2+1;
    df    = 1./(nfft*d1);
    scale = 1./nfft;
    cfg   = kiss_fftr_alloc(nfft,0,NULL,NULL);
    icfg  = kiss_fftr_alloc(nfft,1,NULL,NULL);
    fft1  = sf_complexalloc(nf);
    fft2  = sf_complexalloc(nf);
    if(verbose>0)fprintf(stderr,"fmax=%f\n",(nf-1)*df);

    /* allocate input and output traces with enough padding for
       ffts */
    if(verbose>0)
      fprintf(stderr,"allocate padded intrace.  n1_traces=%d nfft=%d\n",
	                                        n1_traces,   nfft);
    intrace       =sf_floatalloc(nfft); /* must be padded for input to fft */
    bandlimittrace=sf_floatalloc(nfft); /* must be padded for input to fft */
    outtrace= sf_floatalloc(n1_traces);
    rmsall        =sf_floatalloc(n1_traces);
    rmsband        =sf_floatalloc(n1_traces);
    scalars       =sf_floatalloc(n1_traces);
    sum_of_scalars=sf_floatalloc(n1_traces);
    num_centerfreq=(fmax-fmin)/finc+1.95;
    if(fabs(fmax-(fmin+(num_centerfreq-1)*finc))>.01){
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"fmin-fmax is not a multiple of finc\n");
      fprintf(stderr,"fmin=%f, fmax=%f, finc=%f\n",fmin,fmax,finc);
      fprintf(stderr,"*************************************\n");
      fprintf(stderr,"*************************************\n");
      sf_error("illegal combination of fmin,fmax,fminc");
    }

    /***************************/
    /* start trace loop        */
    /***************************/
    if(verbose>0)fprintf(stderr,"start trace loop\n");
 
    itrace=0;
    while (!(get_tah(intrace, fheader, n1_traces, n1_headers, in))){
	if(verbose>1 || (verbose==1 && itrace<5)){
	    fprintf(stderr,"process tah %d in sftahagc\n",itrace);
	}
	/********************/
	/* process the tah. */
	/********************/

	if(typehead == SF_INT)offset=((int  *)fheader)[indx_of_offset];
	else                  offset=((float*)fheader)[indx_of_offset];
	/* maybe latter add agc design start time
	intlin(numxstart,xstart,tstart,
	       tstart[0],tstart[numxstart-1],1,
	       &offset,&time_start);
	if(time_start<o1)time_start=o1;

	itime_start=(int)(((time_start-o1)/d1)+.5);
	*/
	/* find firstlive and lastlive */
        if(verbose>2)fprintf(stderr,"find firstlive and lastlive\n");
	for (firstlive=0; firstlive<n1_traces; firstlive++){
	  if(intrace[firstlive] != 0) break;
	}
	for (lastlive=n1_traces-1;lastlive>=0; lastlive--){
	  if(intrace[lastlive] != 0) break;
	}
	/* kls need to catch a zero trace */
        if(verbose>2)
	  fprintf(stderr,"firstlive=%d, lastlive=%d\n",firstlive,lastlive);
	/* zero the padded area on the input trace */
	for (indx_time=n1_traces; indx_time<nfft; indx_time++){
	  intrace[indx_time]=0;
	}
	
	/********************************************************/
	/* apply the SPECtral BALancing:                        */
	/* 1 compute the input trace rms in agclen gates        */
	/* 2 fft to frequency domain                            */
	/* 3 for each frequency band                            */
	/*   3.1 extract (ramp) the frequency band              */
	/*   3.2 convert freqency band to time,                 */
	/*   3.3 compute the rms of the frequency band          */
	/*   3.4 agc scalars 1/(freq_band_rms + whitenoise*rms) */ 
	/*   3.3 agc the frequency band                         */
	/*   3.4 sum to output                                  */
        /*   3.5 sum scalars to sum of scalars                  */
	/* 4 divide by the sum of scalars                       */
	/********************************************************/
	compute_rms(intrace, rmsall,
		    lenagc, n1_traces,
                    firstlive, lastlive);
	/* scale rms by whitenoise factor */
	if(verbose>2)fprintf(stderr,"put_tah rmsall\n");
	if(0) put_tah(intrace, fheader, n1_traces, n1_headers, out);
        if(0) put_tah(rmsall, fheader, n1_traces, n1_headers, out);
	for (indx_time=0; indx_time<n1_traces; indx_time++){
	  rmsall[indx_time]*=(1.0/num_centerfreq);
	}

	if(verbose>2)fprintf(stderr,"fftr\n");
	kiss_fftr(cfg, intrace, (kiss_fft_cpx*) fft1);

	/* zero the output trace and the sum_of_scalars */
	for (indx_time=0; indx_time<n1_traces; indx_time++){
	  outtrace[indx_time]=0.0;
	  sum_of_scalars[indx_time]=0.0;
	}
	for (cntrfreq=fmin; cntrfreq<=fmax; cntrfreq+=finc){
	  if(verbose>2)fprintf(stderr,"cntrfreq=%f\n",cntrfreq);
          /* zero frequencies before the band */
	  for (ifreq=0; ifreq<(int)((cntrfreq-finc)/df); ifreq++){
	    fft2[ifreq]=0.0;
	  }
	  /* triangular weight the selected  frequency band */
	  for (ifreq=(int)((cntrfreq-finc)/df); 
	       ifreq<(int)((cntrfreq+finc)/df) && ifreq<nf;
	       ifreq++){
            float weight;
	    if(ifreq>0){
	      weight=(1.0-fabs(ifreq*df-cntrfreq)/finc)/nfft;
	      fft2[ifreq]=weight*fft1[ifreq];
	    }
	  }
          /* zero frequencies larger than the band */
	  for (ifreq=(int)((cntrfreq+finc)/df); ifreq<nf; ifreq++){
	    fft2[ifreq]=0.0;
	  } 
	  /* inverse fft back to time domain */
          if(verbose>2)fprintf(stderr,"fftri\n");
	  kiss_fftri(icfg,(kiss_fft_cpx*) fft2, bandlimittrace);
          /* apply agc to the bandlimittrace and sum scalars to 
             sum_of_scalars */
	  if(verbose>2)fprintf(stderr,"agc_apply\n");
	  compute_rms(bandlimittrace, rmsband,
		    lenagc, n1_traces,
                    firstlive, lastlive);
	  if(verbose>2)fprintf(stderr,"sum to ouput\n");
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    /* old poor 
	       scalars[indx_time]=1.0/
                   (rmsband[indx_time]+pnoise*rmsall[indx_time]);
	    */
	    if(1)scalars[indx_time]=rmsband[indx_time]/
                     (rmsband[indx_time]*rmsband[indx_time]+
		      pnoise*rmsall[indx_time]*rmsall[indx_time]);
	    else scalars[indx_time]=1.0;
	  }
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    bandlimittrace[indx_time]*=scalars[indx_time];
	    outtrace[indx_time]+=bandlimittrace[indx_time];
	  }
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    sum_of_scalars[indx_time]+=scalars[indx_time];
	  }
          if(0)
	    put_tah(bandlimittrace, fheader, n1_traces, n1_headers, out);
	  if(0)
	    put_tah(rmsband, fheader, n1_traces, n1_headers, out);
	  if(0)
	    put_tah(scalars, fheader, n1_traces, n1_headers, out);
	}
        if(0)put_tah(sum_of_scalars, fheader, n1_traces, n1_headers, out);
        if(1){	
	   /* divide output by sum of scalars */
	  for (indx_time=0; indx_time<n1_traces; indx_time++){
	    outtrace[indx_time]/=sum_of_scalars[indx_time];
	  }
	} 
	if (1)
	  put_tah(outtrace, fheader, n1_traces, n1_headers, out);
	itrace++;
    }

    exit(0);
}
Beispiel #19
0
void velcon(float ** data /* [nx][nt] */,
	    float v0      /* initial velocity */,
	    float v1      /* new velocity */)
/*< apply velocity continuation >*/
{
    int it, ix, i2, iw;
    float *trace, k, w, t;
    sf_complex shift;

    for (it=0; it < nt; it++) {
	sf_cosft_frw (data[0], it, nt);
    }

    for (ix=0; ix < nx; ix++) {
	/* loop over wavenumbers */
	k = ix*dx;
	k *= k*(v0*v0 - v1*v1)/16;

	trace = data[ix];

	/* stretch t -> t^2 */

	for (it=0; it < nt; it++) {
	    trace[it] /= nt;
	}

	fint1_set(str,trace);

	for (i2=0; i2 < n2; i2++) {
	    t = o2+i2*d2;
	    t = sqrtf(t);
	    t = (t-t0)/dt;
	    it = t;
	    if (it >= 0 && it < nt) {
		strace[i2] = fint1_apply(str,it,t-it,false);
	    } else {
		strace[i2] = 0.;
	    }
	}

	for (i2=n2; i2 < n3; i2++) {
	    strace[i2] = 0.;
	}

	/* FFT */

	kiss_fftr(forw,strace, (kiss_fft_cpx *) ctrace);

	/* velocity continuation */

	ctrace[0]=sf_cmplx(0.,0.); /* dc */

	for (iw=1; iw < nw; iw++) {
	    w = iw*dw;
	    w = k/w;
	    shift = sf_cmplx(cosf(w)/n3,sinf(w)/n3);

#ifdef SF_HAS_COMPLEX_H
	    ctrace[iw] *= shift;
#else
	    ctrace[iw] = sf_cmul(ctrace[iw],shift);
#endif
	}

	/* Inverse FFT */

	kiss_fftri(invs,(const kiss_fft_cpx *) ctrace, strace);

	/* inverse stretch t^2->t */

	fint1_set(istr,strace);

	for (it=0; it < nt; it++) {
	    t = t0+it*dt;
	    t = t*t;
	    t = (t-o2)/d2;
	    i2 = t;
	    if (i2 >= 0 && i2 < n2) {
		trace[it] = fint1_apply(istr,i2,t-i2,false);
	    } else {
		trace[it] = 0.;
	    }
	}	
    } /* ix */

    /* inverse cosine FT in space */
    for (it=0; it < nt; it++) {
	sf_cosft_inv (data[0], it, nt);
    }
}
Beispiel #20
0
/* real-to-complex transform in 1 dimension */
int tcl_rfft_1d(ClientData nodata, Tcl_Interp *interp,
                int objc, Tcl_Obj *const objv[]) 
{
    Tcl_Obj *result, **tdata;
    
    const char *name;
    kiss_fft_scalar *timed;
    kiss_fft_cpx    *freqd;
    kiss_fftr_cfg    work;
    
    int dir, ndat, k;

    /* thread safety */
    Tcl_MutexLock(&myFftMutex);

    /* set defaults: */
    dir   = FFT_FORWARD;
    ndat  = -1;
    
    /* Parse arguments:
     *
     * usage: r2cfft_1d <data>
     *    or: c2rfft_1d <data>
     * 
     * r2cfftf_1d : is the 1d real-to-complex forward transform.
     * c2rfftb_1d : is the 1d complex-to-real backward transform.
     * <data>     : list containing data to be transformed. this can either a real 
     *              or a list with two reals interpreted as complex.
     */

    name = Tcl_GetString(objv[0]);
    if (strcmp(name,"r2cfft_1d") == 0) {
        dir = FFT_FORWARD;
    } else if (strcmp(name,"c2rfft_1d") == 0) {
        dir = FFT_BACKWARD;
    } else {
        Tcl_AppendResult(interp, name, ": unknown fft command.", NULL);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "<data>");
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    
    /* get handle on data */
    Tcl_IncrRefCount(objv[1]);
    if (Tcl_ListObjGetElements(interp, objv[1], &ndat, &tdata) != TCL_OK) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if (ndat < 0) {             /* this should not happen, but... */
        Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    /* no effect for zero or one element */
    if ((ndat == 0) || (ndat == 1)) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_SetObjResult(interp, objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_OK;
    }

    /* we need an even number of data points for the forward transform */
    if (ndat & 1) {
        if (dir == FFT_FORWARD) {
            Tcl_AppendResult(interp, name, " needs an even number of data points.", NULL);
            Tcl_DecrRefCount(objv[1]);
            Tcl_MutexUnlock(&myFftMutex);
            return TCL_ERROR;
        }
    }

    check_thread_count(interp,"fftcmds");

    /* size of data arrays for backward transform */
    if (dir == FFT_BACKWARD) ndat = (ndat-1)*2;
    
    /* get dynamic storage for passing data to the lowlevel code. */
    timed = (void *)Tcl_Alloc(ndat*sizeof(kiss_fft_scalar));
    freqd = (void *)Tcl_Alloc((ndat/2+1)*sizeof(kiss_fft_cpx));
    work  = kiss_fftr_alloc(ndat, dir, NULL, NULL);
    
    /* parse/copy data list */
    if (dir == FFT_FORWARD) {
        for (k=0; k<ndat; ++k) {
            if (Tcl_GetDoubleFromObj(interp, tdata[k], timed + k) != TCL_OK) {
                Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
                Tcl_DecrRefCount(objv[1]);
                Tcl_MutexUnlock(&myFftMutex);
                return TCL_ERROR;
            }
        }
    } else {
        for (k=0; k<(ndat/2)+1; ++k) {
            if (read_list_cpx(interp, tdata[k], freqd + k) != TCL_OK) {
                Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
                Tcl_DecrRefCount(objv[1]);
                Tcl_MutexUnlock(&myFftMutex);
                return TCL_ERROR;
            }
        }
    }
    Tcl_DecrRefCount(objv[1]);
    
    /* finally run the transform */
    if (dir == FFT_FORWARD) {
        kiss_fftr(work, timed, freqd);
    } else {
        kiss_fftri(work, freqd, timed);
    }

    /* prepare results */
    result = Tcl_NewListObj(0, NULL);
    if (dir == FFT_FORWARD) {
        for (k=0; k<(ndat/2)+1; ++k) {
            make_list_cpx(interp, result, freqd + k);
        }
    } else {
        for (k=0; k<ndat; ++k) {
            Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(timed[k]));
        }
    }
    Tcl_SetObjResult(interp, result);

    /* free intermediate storage */
    Tcl_Free((char *)timed);
    Tcl_Free((char *)freqd);
    kiss_fft_free(work);
    kiss_fft_cleanup();

    Tcl_MutexUnlock(&myFftMutex);
    return TCL_OK;
}
Beispiel #21
0
void fft1_2D (float *field, float *Field, int n2, bool inv)
/*< Fast Fourier Transform along the first axis >*/
{
    /*bool inv, sym, opt;*/
    int n1, i1, i2;
    float  *p,  wt, shift;
    kiss_fft_cpx *pp, ce;
    char *label;
    sf_file out=NULL;
    kiss_fftr_cfg cfg;
	bool verb;

	verb=1;

    
    
  p = sf_floatalloc(ntopt);
  pp = (kiss_fft_cpx*) sf_complexalloc(nw);

  cfg = kiss_fftr_alloc(ntopt,inv?1:0,NULL,NULL);
  wt = sym? 1./sqrtf((float) ntopt): 1.0/ntopt;

    
  if(!inv) sf_warning("gforward fft");
  if(inv) sf_warning("inverse fft");

	for (i2=0; i2 < n2; i2++) {

    	if(inv) {
    	    /*sf_floatread((float*) pp,2*nw,in);*/
    		  memcpy(pp,&field[i2*2*nw],2*nw*sizeof(float));
    
    	    if (0. != ot) {
    		    for (i1=0; i1 < nw; i1++) {
    		      shift = +2.0*SF_PI*i1*dw*ot;
    		      ce.r = cosf(shift);
    		      ce.i = sinf(shift);
    		      pp[i1]=sf_cmul(pp[i1],ce);
    		    }
    	    }
    
    	    kiss_fftri(cfg,pp,p);
    
    	    for (i1=0; i1 < n1; i1++) {
    		    p[i1] *= wt;
    	    }
    
    		  memcpy(&Field[i2*n1],p,n1*sizeof(float));
    	    /*sf_floatwrite (p,n1,out);*/
    	}else{
    	    /*sf_floatread (p,n1,in);*/
          n1 = ntopt;
          sf_warning("i2=%d n1=%d",i2,n1); 
    	    memcpy(p,&field[i2*n1],n1*sizeof(float));
    	    if (sym) {
        		for (i1=0; i1 < n1; i1++) {
      		    p[i1] *= wt;
    	    	}
    	    }
    
    	    for (i1=n1; i1 < ntopt; i1++) {
    		    p[i1]=0.0; // padding
    	    }
    
    	    kiss_fftr (cfg,p,pp);
    
    	    if (0. != ot) {
    		    for (i1=0; i1 < nw; i1++) {
    		      shift = -2.0*SF_PI*i1*dw*ot;
    		      ce.r = cosf(shift);
    		      ce.i = sinf(shift);
    		      pp[i1]=sf_cmul(pp[i1],ce);
    		    }
    	    }
    		
    		  memcpy(&Field[i2*2*nw],pp,2*nw*sizeof(float));
      }
    
    }

	free(p);
	free(pp);

    
	/*exit (0);*/
}
Beispiel #22
0
void freqfilt4pi_lop (bool adj, bool add, int nx, int ny, float* x, float* y) 
/*< linear filtering operator >*/
{
    int iw, ik;
    kiss_fft_cpx temp;
    int verb; // just outputting values to check when I get zeroes

    sf_adjnull(adj,add,nx,ny,x,y);

    for (ik=0; ik < m2; ik++) {
	for (iw=0; iw < m1; iw++) {
	    trace[iw] = adj? y[ik*m1+iw]: x[ik*m1+iw];
	
		/*if(trace[iw] == 0.0){
		
			sf_warning("trace[%d] = %f",iw,trace[iw]);
			
		}*/
	
	}
	for (iw=m1; iw < nfft; iw++) {
	    trace[iw]=0.;
	}

	kiss_fftr (tfor,trace,ctrace);
	for (iw=0; iw < nw; iw++) {
	    fft[ik][iw] = ik%2? sf_cneg(ctrace[iw]): ctrace[iw];
	}
    }

    for (iw=0; iw < nw; iw++) {
	kiss_fft_stride(xfor,fft[0]+iw,ctrace2,nw);

	for (ik=0; ik < m2; ik++) {
	
		//double creal( double complex z );
	
	    //transform to kiss fft cpx
	    //creal are double complex functions - what should we
	    //do when double complex is not supported???  	
		if (adj){
			temp.r = creal(shape[iw][ik]);
			temp.i = (-1.0)*cimag(shape[iw][ik]);
		} else {
			temp.r = creal(shape[iw][ik]);
			temp.i = cimag(shape[iw][ik]);
	    }
	    
	    ctrace2[ik] = sf_cmul(ctrace2[ik],temp);
	
	}

	kiss_fft(xinv,ctrace2,ctrace2);

	for (ik=0; ik < m2; ik++) {
	    fft[ik][iw] = ik%2? sf_cneg(ctrace2[ik]): ctrace2[ik];
	}
    }

    for (ik=0; ik < m2; ik++) {
	kiss_fftri (tinv,fft[ik],trace);

	for (iw=0; iw < m1; iw++) {	  
	    if (adj) {
		x[ik*m1+iw] += trace[iw];
	    } else {
		y[ik*m1+iw] += trace[iw];
	    }
	}
    }
}
int
main(int argc, char **argv)
{
	//int nt;			/* number of frequency samples per trace */
  int nfft;   /* For computing the FFT */
	//float dw;		/* time sampling interval */
	//int i1;			/* time sample index */
  //int log;   /* Check if the trace has had a log applied (for mie scattering) */
  int j;     /* Other indices */
  const double eps = 1.e-32;
  kiss_fftr_cfg forw, invs;

  /* Variables for Jons example */
  float *spectrum  = NULL;
  float *rspectrum = NULL;
  complex *fft     = NULL;
  int n            = 64;
  int nw           = n/2+1;
  float o1         = -M_PI/2;
  float d1         = M_PI/n;

  nfft = n;

	/* hook up getpar */
	initargs(argc, argv);
	//requestdoc(1);
  requestdoc(0); // For now (testing), stdin is not used

  /* Allocating memory */
  spectrum  = ealloc1float((n+1));
  rspectrum = ealloc1float((n/2+1));
  fft       = alloc1complex(nfft/2+1);
  forw      = kiss_fftr_alloc(nfft,0,NULL,NULL);
  invs      = kiss_fftr_alloc(nfft,1,NULL,NULL);
  if(NULL == forw || NULL == invs)
    err("KISS FFT allocation error");
  memset( (void *) tr.data, 0, (n+1) * FSIZE);

  tr.dt = d1;
  tr.f1 = o1;
  tr.ns = n;
  create_spectrum(n, o1, d1, spectrum);

  /* Squaring the spectrum */
  j = n/2;
  for(int i = 0; i < nw; i++, j++) {
    rspectrum[i] = spectrum[j]*spectrum[j];
    tr.data[i] = rspectrum[i];
  }

 
  fprintf(stderr, "Created input: \n"); 
  for(int i = 0; i < nw; i++) {
    fprintf(stderr, "i=%d input=%f\n",i,rspectrum[i]);
  }
  fprintf(stderr, "\n");

  // Take the log and create a complex type
  //fprintf(stderr, "Log of spectrum: \n"); 
  for(int i = 0; i < nw; i++) {
    fft[i] = cmplx(log(rspectrum[i]+eps)/nfft,0.);
  }
  //for(int i = 0; i < nw; i++) {
  //  fprintf(stderr, "i=%d real=%f imag=%f\n",i,fft[i].r,fft[i].i);
  //}
  //fprintf(stderr, "\n");

  // Find the inverse FFT
  kiss_fftri(invs,(const kiss_fft_cpx *) fft, tr.data);

  tr.data[0]      *= 0.5;
  tr.data[nfft/2] *= 0.5;
  for(int i=1+nfft/2; i < nfft; i++) {
    tr.data[i] = 0;
  }

  kiss_fftr(forw, tr.data, (kiss_fft_cpx *) fft);

  for(int i=0; i < nw; i++) {
    fft[i] = crmul(cwp_cexp(fft[i]),1./nfft);
  }

  kiss_fftri(invs,(const kiss_fft_cpx *) fft, tr.data);

  float dt = 0.004;
  for(int i = 0; i < nfft; i++) {
    fprintf(stderr, "i=%d t=%f output=%f\n", i, o1+dt*i, tr.data[i]);
  }

  puttr(&tr);
	return(CWP_Exit());
}
Beispiel #24
0
void MainContentComponent::buttonClicked (Button* buttonThatWasClicked)
{
    //[UserbuttonClicked_Pre]
    //[/UserbuttonClicked_Pre]

    if (buttonThatWasClicked == convButton)
    {
        //[UserButtonCode_convButton] -- add your button handler code here..
		const ScopedLock fl(soundListLock);

		setPlayheadUiEnabled(false);

		bool convValid = true;

		float q;
		float s;
		double nfft;
		{
			const ScopedLock pl(paramLock);
			q = qParam;
			s = sParam;
			nfft = static_cast<double>(nfftParam);
		}

		int fftInputLen = static_cast<int>(std::pow(2.0, nfft));
		int fftOutputLen = fftInputLen / 2 + 1;
		int numChannels = 1;

		unordered_set<int> includedSounds;
		int maxChannels = 0;
		float pSum = 0.0f;
		float rSum = 0.0f;
		for (const auto& iter : idToSound) {
			int id = iter.first;
			Sound* sound = iter.second.get();
			int numChannels = sound->getBufferNumChannels();
			if (sound->isIncluded() && numChannels > 0) {
				maxChannels = numChannels > maxChannels ? numChannels : maxChannels;
				includedSounds.emplace(id);
				pSum += static_cast<float>(sound->getPValue());
				rSum += static_cast<float>(sound->getRValue());
			}
		}
		float n = static_cast<float>(includedSounds.size());
		float pScale = n * q / pSum;
		float rScale = n * s / rSum;

		if (maxChannels == 0) {
			return;
		}

		kiss_fftr_state* fftInverseState = kiss_fftr_alloc(fftInputLen, 1, nullptr, nullptr);
		kiss_fft_cpx* CONV = static_cast<kiss_fft_cpx*>(calloc(fftOutputLen * maxChannels, sizeof(kiss_fft_cpx)));
		conv.setSize(maxChannels, fftInputLen);

		float max = -1.0f;

		// convolve
		for (int convChannel = 0; convChannel < maxChannels; ++convChannel) {
			kiss_fft_cpx* CONVCHANNEL = CONV + (convChannel * fftOutputLen);

			bool isFirstSound = true;
			for (const auto& id : includedSounds) {
				Sound* sound = idToSound[id].get();
				jassert(sound != nullptr);
				float p = pScale * static_cast<float>(sound->getPValue());
				float r = rScale * static_cast<float>(sound->getRValue());
				int soundNumChannels = sound->getBufferNumChannels();
				int soundNumSamples = sound->getBufferNumSamples();
				int soundChannel = convChannel >= soundNumChannels ? soundNumChannels - 1 : convChannel;
				const kiss_fft_cpx* SOUNDCHANNEL = sound->getSpectra(fftInputLen, soundChannel);

				for (int i = 0; i < fftOutputLen; ++i) {
					float xr = SOUNDCHANNEL[i].r;
					float xi = SOUNDCHANNEL[i].i;
					float xMag = sqrtf((xr * xr) + (xi * xi));
					float xPhs = atan2f(xi, xr);
					float convMag = powf(xMag, p);
					float convPhs = r * xPhs;
					float convr = convMag * cosf(convPhs);
					float convi = convMag * sinf(convPhs);

					if (std::isnan(convr) || std::isnan(convi)) {
						convValid = false;
					}

					if (isFirstSound) {
						CONVCHANNEL[i].r = convr;
						CONVCHANNEL[i].i = convi;
					}
					else {
						float a = CONVCHANNEL[i].r;
						float b = CONVCHANNEL[i].i;
						float c = convr;
						float d = convi;
						CONVCHANNEL[i].r = a * c - b * d;
						CONVCHANNEL[i].i = a * d + b * c;
					}
				}

				isFirstSound = false;
			}

			// ifft
			kiss_fftri(fftInverseState, CONVCHANNEL, conv.getWritePointer(convChannel));

			// check max
			float channelMax = conv.findMinMax(convChannel, 0, fftInputLen).getEnd();
			max = channelMax > max ? channelMax : max;
		}

		delete fftInverseState;
		delete CONV;

		// normalize
		conv.applyGain(1.0f / max);

		if (!convValid) {
			AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Error", "Parameters produced NaN value.");
			return;
		}

		setPlayheadAudio(&conv);
        //[/UserButtonCode_convButton]
    }
    else if (buttonThatWasClicked == settingsButton)
    {
        //[UserButtonCode_settingsButton] -- add your button handler code here..
		AudioDeviceSelectorComponent audioSettingsComp(deviceManager,
			0, 256,
			0, 256,
			true, true, true, false);

		audioSettingsComp.setSize(500, 450);

		DialogWindow::LaunchOptions o;
		o.content.setNonOwned(&audioSettingsComp);
		o.dialogTitle = "Audio Settings";
		o.componentToCentreAround = this;
		o.dialogBackgroundColour = Colours::azure;
		o.escapeKeyTriggersCloseButton = true;
		o.useNativeTitleBar = false;
		o.resizable = false;

		o.runModal();

		ScopedPointer<XmlElement> audioState(deviceManager.createStateXml());

		getAppProperties().getUserSettings()->setValue("audioDeviceState", audioState);
		getAppProperties().getUserSettings()->saveIfNeeded();
        //[/UserButtonCode_settingsButton]
    }
    else if (buttonThatWasClicked == playButton)
    {
        //[UserButtonCode_playButton] -- add your button handler code here..
		const ScopedLock pal(playheadAudioLock);
		playheadState = PlayheadState::playing;
		playheadAudioSamplesCompleted = 0;
        //[/UserButtonCode_playButton]
    }
    else if (buttonThatWasClicked == loopButton)
    {
        //[UserButtonCode_loopButton] -- add your button handler code here..
		const ScopedLock pal(playheadAudioLock);
		playheadState = PlayheadState::looping;
        //[/UserButtonCode_loopButton]
    }
    else if (buttonThatWasClicked == stopButton)
    {
        //[UserButtonCode_stopButton] -- add your button handler code here..
		const ScopedLock pal(playheadAudioLock);
		playheadState = PlayheadState::stopped;
		playheadAudioSamplesCompleted = 0;
        //[/UserButtonCode_stopButton]
    }
    else if (buttonThatWasClicked == qDefaultButton)
    {
        //[UserButtonCode_qDefaultButton] -- add your button handler code here..
		qSlider->setValue(1.0);
        //[/UserButtonCode_qDefaultButton]
    }
    else if (buttonThatWasClicked == sDefaultButton)
    {
        //[UserButtonCode_sDefaultButton] -- add your button handler code here..
		sSlider->setValue(1.0);
        //[/UserButtonCode_sDefaultButton]
    }
    else if (buttonThatWasClicked == saveButton)
    {
        //[UserButtonCode_saveButton] -- add your button handler code here..
		const ScopedLock pal(playheadAudioLock);

		if (playheadAudio.getNumChannels() > 0 && playheadAudio.getNumSamples() > 0) {
			FileChooser fileChooser("Save as...", File::nonexistent, "*.wav", true);
			if (fileChooser.browseForFileToSave(true)) {
				File outputFile = fileChooser.getResult();
				outputFile.deleteFile();
				WavAudioFormat wavFormat;
				ScopedPointer<FileOutputStream> outputFileStream = outputFile.createOutputStream();
				ScopedPointer<AudioFormatWriter> writer = wavFormat.createWriterFor(outputFileStream, 44100.0, playheadAudio.getNumChannels(), 16, StringPairArray(), 0);
				writer->writeFromAudioSampleBuffer(playheadAudio, 0, playheadAudio.getNumSamples());
				outputFileStream.release();
			}
		}
        //[/UserButtonCode_saveButton]
    }
    else if (buttonThatWasClicked == inputRemoveButton)
    {
        //[UserButtonCode_inputRemoveButton] -- add your button handler code here..
		const ScopedLock fl(soundListLock);
		SparseSet<int> selectedRows = inputFileListComponent->getSelectedRows();
		for (int i = 0; i < selectedRows.size(); ++i) {
			int row = selectedRows[i];
			int id = inputFileListComponent->getIdForRow(row);
			const auto& iter = idToSound.find(id);
			jassert(iter != idToSound.end());
			idToSound.erase(iter);
		}
		if (selectedRows.size() > 0) {
			inputFilesChanged(dontSendNotification);
		}
        //[/UserButtonCode_inputRemoveButton]
    }
    else if (buttonThatWasClicked == inputAddButton)
    {
        //[UserButtonCode_inputAddButton] -- add your button handler code here..
		const ScopedLock fl(soundListLock);
		FileChooser fileChooser("Add sound...", File::nonexistent, "*.wav;*.aif;*.aiff;*.ogg", true);
		if (fileChooser.browseForMultipleFilesToOpen()) {
			Array<File> files = fileChooser.getResults();
			StringArray filePaths;
			for (int i = 0; i < files.size(); ++i) {
				filePaths.add(files[i].getFullPathName());
			}
			filesDropped(filePaths, -1, -1);
		}
        //[/UserButtonCode_inputAddButton]
    }

    //[UserbuttonClicked_Post]
    //[/UserbuttonClicked_Post]
}
Beispiel #25
0
int main(int argc, char* argv[])
{
    fint1 str, istr;
    int i1,i2, n1,n2,n3, ix,iv,ih, nx,nv,nh, nw, next;
    float d1,o1,d2,o2, eps, w,x,k, v0,v2,v,v1,dv, dx, h0,dh,h, t, t2;
    float *trace, *strace, ***prev, ***semb, ***cont, **image;
    float complex *ctrace, *ctrace0;
    static kiss_fftr_cfg forw, invs;
    sf_file in, out;

    sf_init (argc,argv);
    in = sf_input("in");
    out = sf_output("out");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&nx)) sf_error("No n2= in input");
    if (!sf_histint(in,"n3",&nh)) sf_error("No n3= in input");

    if (!sf_getfloat("eps",&eps)) eps=0.01;
    if (!sf_getint("pad",&n2)) n2=n1;
    if (!sf_getint("pad2",&n3)) n3=n2;

    if (n3%2) n3++;
    nw = n3/2+1;
    forw = kiss_fftr_alloc(n3,0,NULL,NULL);
    invs = kiss_fftr_alloc(n3,1,NULL,NULL);
    if (NULL == forw || NULL == invs) 
	sf_error("KISS FFT allocation error");

    if (!sf_histfloat(in,"o1",&o1)) o1=0.;  
    o2 = o1*o1;
 
    if(!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input");
    d2 = o1+(n1-1)*d1;
    d2 = (d2*d2 - o2)/(n2-1);

    if (!sf_getint("nv",&nv)) sf_error("Need nv=");
    if (!sf_getfloat("dv",&dv)) sf_error("Need dv=");
    if (!sf_getfloat("v0",&v0) && 
	!sf_histfloat(in,"v0",&v0)) sf_error("Need v0=");

    if(!sf_histfloat(in,"o3",&h0)) sf_error("No o2= in input");
    if(!sf_histfloat(in,"d3",&dh)) sf_error("No d2= in input");
    if(!sf_histfloat(in,"d2",&dx)) sf_error("No d3= in input");
    
    sf_putfloat(out,"o3",v0+dv);
    sf_putfloat(out,"d3",dv);
    sf_putint(out,"n3",nv);

    sf_putstring(out,"label3","Velocity (km/s)");

    dx = 2.*SF_PI/(2*(nx-1)*dx);

    prev = sf_floatalloc3(n1,nx,nv);
    semb = sf_floatalloc3(n1,nx,nv);
    cont = sf_floatalloc3(n1,nx,nv);
    image = sf_floatalloc2(n1,nx);
    trace = sf_floatalloc(n1);
    strace = sf_floatalloc(n3);
    ctrace = sf_complexalloc(nw);
    ctrace0 = sf_complexalloc(nw);

    if (!sf_getint("extend",&next)) next=4;
    /* trace extension */
    str = fint1_init(next,n1,0);
    istr = fint1_init(next,n2,0);

    for (i1=0; i1 < n1*nx*nv; i1++) {
	semb[0][0][i1] = 0.;
    }

    cosft_init(nx);

    for (ih=0; ih < nh; ih++) {
	sf_warning("offset %d of %d",ih+1,nh);

	h = h0 + ih*dh;
	h *= h;

	sf_floatread(image[0],n1*nx,in);

	for (i1=0; i1 < n1; i1++) {
	    cosft_frw(image[0],i1,n1);
	}

	for (ix=0; ix < nx; ix++) {
	    x = ix*dx; 
	    x *= x;

	    k = x * 0.25 * 0.25 * 0.5;

	    fint1_set(str,image[ix]);

	    for (i2=0; i2 < n2; i2++) {
		t = o2+i2*d2;
		t = sqrtf(t);
		t = (t-o1)/d1;
		i1 = t;
		if (i1 >= 0 && i1 < n1) {
		    strace[i2] = fint1_apply(str,i1,t-i1,false);
		} else {
		    strace[i2] = 0.;
		}
	    }
	    
	    for (i2=n2; i2 < n3; i2++) {
		strace[i2] = 0.;
	    }
		
	    kiss_fftr(forw,strace, (kiss_fft_cpx *) ctrace0);   

	    for (iv=0; iv < nv; iv++) {
		v = v0 + (iv+1)* dv;

		v1 = h * (1./(v*v) - 1./(v0*v0)) * 8.;
		v2 = k * ((v0*v0) - (v*v));

		ctrace[0]=0.; /* dc */

		for (i2=1; i2 < nw; i2++) {
		    w = i2*SF_PI/(d2*n3);
 
		    ctrace[i2] = ctrace0[i2] * cexpf(I*(v2/w+(v1-o2)*w));
		} /* w */

		kiss_fftri(invs,(const kiss_fft_cpx *) ctrace, strace);
		
		fint1_set(istr,strace);
		
		for (i1=0; i1 < n1; i1++) {
		    t = o1+i1*d1;
		    t = t*t;
		    t = (t-o2)/d2;
		    i2 = t;
		    if (i2 >= 0 && i2 < n2) {
			cont[iv][ix][i1] = fint1_apply(istr,i2,t-i2,false);
		    } else {
			cont[iv][ix][i1] = 0.;
		    }
		}
	    } /* v */
	} /* x */

	for (iv=0; iv < nv; iv++) {
	    for (i1=0; i1 < n1; i1++) {
		cosft_inv(cont[0][0],i1+iv*nx*n1,n1);
	    }
	}

	for (iv=0; iv < nv; iv++) {
	    for (ix=0; ix < nx; ix++) {
		for (i1=0; i1 < n1; i1++) {	
		    t = cont[iv][ix][i1];
		    if (ih > 0) {
			t2 = prev[iv][ix][i1]-t;
			semb[iv][ix][i1] += t2*t2;
		    }
		    prev[iv][ix][i1] = t;
		} /* i1 */
	    } /* x */
        } /* v */
    } /* h */

    sf_floatwrite (semb[0][0],n1*nx*nv,out);

    exit(0);
}
Beispiel #26
0
int main(int argc, char* argv[]) 
{
    int nx, nt, nk, ik, ix, it, nft;
    float dt, dx, dk, k;
    float *old, *nxt, *cur, *sig, *v, *nxttmp, v0, **aa, tv, tv0, dv, pi=SF_PI, tmpk;
    sf_file in, out, vel;
    bool opt;    /* optimal padding */
    sf_complex  *uk, *uktmp; 
    kiss_fftr_cfg cfg, cfgi;

    sf_init(argc,argv);
    in  = sf_input("in");
    vel = sf_input("vel");   /* velocity */
    out = sf_output("out");

    if (SF_FLOAT != sf_gettype(in)) sf_error("Need float input");
    if (SF_FLOAT != sf_gettype(vel)) sf_error("Need float input");
    if (!sf_histint(vel,"n1",&nx)) sf_error("No n1= in input");
    if (!sf_histfloat(vel,"d1",&dx)) sf_error("No d1= in input");
    if (!sf_getbool("opt",&opt)) opt=true;
    if (!sf_getfloat("dt",&dt)) sf_error("Need dt input");
    if (!sf_getint("nt",&nt)) sf_error("Need nt input");

    sf_putint(out,"n1",nx);
    sf_putfloat(out,"d1",dx);
//    sf_putfloat(out,"o1",x0);
    sf_putint(out,"n2",nt);
    sf_putfloat(out,"d2",dt);
    sf_putfloat(out,"o2",0.0); 

    nft = opt? 2*kiss_fft_next_fast_size((nx+1)/2): nx;
    if (nft%2) nft++;
    nk = nft/2+1;
    dk = 1./(nft*dx);

    sig = sf_floatalloc(nx);
    old = sf_floatalloc(nx);
    nxt = sf_floatalloc(nx);
    nxttmp = sf_floatalloc(nx);
    cur = sf_floatalloc(nx);
    v = sf_floatalloc(nx);
    aa = sf_floatalloc2(2,nx);
    uk = sf_complexalloc(nk);
    uktmp = sf_complexalloc(nk);
    
 
    sf_floatread(v,nx,vel);
    sf_floatread(sig,nx,in);		
    sf_floatwrite(sig,nx,out);

    v0=0.0;
    for (ix=0; ix < nx; ix++) v0 += v[ix]*v[ix];
    v0 /= (float)nx;
    /* v0 RMS velocity*/
    v0 = sqrt(v0);
    tv0 = v0*v0*dt*dt;

    for (ix=0; ix < nx; ix++){
        tv = dt*dt*v[ix]*v[ix];
        dv = (v[ix]*v[ix]-v0*v0)*dt*dt/(dx*dx);
        aa[ix][0] = tv*(1.0 - dv/6.0);
        aa[ix][1] = tv*dv/12.0;
    } 
	/* initial conditions */
    for (ix=0; ix < nx; ix++){
        cur[ix] =  sig[ix];
        old[ix] =  0.0; 
	nxt[ix] = 0.;
    }

    free(v);
    free(sig);

    cfg = kiss_fftr_alloc(nft,0,NULL,NULL); 
    cfgi = kiss_fftr_alloc(nft,1,NULL,NULL); 
    /* propagation in time */
    for (it=1; it < nt; it++) {
	kiss_fftr(cfg,cur,(kiss_fft_cpx*)uk);/*compute  u(k) */
#ifdef SF_HAS_COMPLEX_H
        for (ik=0; ik < nk; ik++) {
            k =  ik * dk*2.0*pi;
            tmpk = v0*fabs(k)*dt;
            uktmp[ik] = uk[ik]*2.0*(cosf(tmpk)-1.0)/tv0;
         }

#else
         for (ik=0; ik < nk; ik++) {
             k =  ik * dk*2.0*pi;
             tmpk = v0*fabs(k)*dt;
             uktmp[ik] = sf_crmul(uk[ik],2.0*(cosf(tmpk)-1.0)/tv0);
         }
#endif
	 kiss_fftri(cfgi,(kiss_fft_cpx*)uktmp,nxttmp);

	for (ix=0; ix < nx; ix++) nxttmp[ix] /= (float)nft; 

	/* Stencil */
	nxt[0] = nxttmp[0]*aa[0][0] + nxttmp[0]*aa[0][0] + nxttmp[1]*aa[0][1];
	for (ix=1; ix < nx-1; ix++) {
	    nxt[ix] = nxttmp[ix]*aa[ix][0] + nxttmp[ix+1]*aa[ix][1] + nxttmp[ix-1]*aa[ix][1];
	}
	nxt[nx-1] = nxttmp[nx-1]*aa[nx-1][1] + nxttmp[nx-1]*aa[nx-1][0] + nxttmp[nx-2]*aa[nx-1][1];
	
	for (ix=0; ix < nx; ix++) {
	    nxt[ix] +=  2*cur[ix] - old[ix];
	}

	sf_floatwrite(nxt,nx,out);
	for (ix=0; ix < nx; ix++) {
	    old[ix] = cur[ix];
	    cur[ix] = nxt[ix];
	}
    }


    exit(0);
}
Beispiel #27
0
int main(int argc, char* argv[])
{
    fint1 str, istr;
    int i1,i2, n1,n2,n3, ix,iv,ih, ib, ie, nb, nx,nv,nh, nw, next;
    float d1,o1,d2,o2, eps, w,x,k, v0,v2,v,v1,dv, dx, h0,dh,h, num, den, t, dw;
    float *trace=NULL, *strace=NULL, ***stack=NULL, ***stack2=NULL, ***cont=NULL, **image=NULL;
    sf_complex *ctrace=NULL, *ctrace0=NULL, shift;
    char *time=NULL, *space=NULL, *unit=NULL;
    size_t len;
    static kiss_fftr_cfg forw, invs;
    sf_file in=NULL, out=NULL;
    bool sembl;

    sf_init (argc,argv);
    in = sf_input("in");
    out = sf_output("out");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&nx)) sf_error("No n2= in input");
    if (!sf_histint(in,"n3",&nh)) sf_error("No n3= in input");

    if (!sf_getint("nb",&nb)) nb=2;
    if (!sf_getfloat("eps",&eps)) eps=0.01;
    if (!sf_getint("pad",&n2)) n2=n1;
    if (!sf_getint("pad2",&n3)) n3=2*kiss_fft_next_fast_size((n2+1)/2);

    nw = n3/2+1;
    forw = kiss_fftr_alloc(n3,0,NULL,NULL);
    invs = kiss_fftr_alloc(n3,1,NULL,NULL);
    if (NULL == forw || NULL == invs) 
	sf_error("KISS FFT allocation error");

    if (!sf_histfloat(in,"o1",&o1)) o1=0.;
    o2 = o1*o1;

    if(!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input");
    d2 = o1+(n1-1)*d1;
    d2 = (d2*d2 - o2)/(n2-1);

    if (!sf_getint("nv",&nv)) sf_error("Need nv=");
    if (!sf_getfloat("dv",&dv)) sf_error("Need dv=");
    if (!sf_getfloat("v0",&v0) && 
	!sf_histfloat(in,"v0",&v0)) sf_error("Need v0=");

    if (!sf_getbool("semblance",&sembl)) sembl=true;
    /* if y, compute semblance; if n, stack */

    if(!sf_histfloat(in,"o3",&h0)) sf_error("No o2= in input");
    if(!sf_histfloat(in,"d3",&dh)) sf_error("No d2= in input");
    if(!sf_histfloat(in,"d2",&dx)) sf_error("No d3= in input");

    sf_putfloat(out,"o3",v0+dv);
    sf_putfloat(out,"d3",dv);
    sf_putint(out,"n3",nv);

    sf_putstring(out,"label3","Velocity");

    if (NULL != (time = sf_histstring(in,"label1")) &&
	NULL != (space = sf_histstring(in,"label2"))) {
	len = strlen(time)+strlen(space)+2;
	unit = sf_charalloc(len);
	snprintf(unit,len,"%s/%s",space,time);
	sf_putstring(out,"unit3",unit);
	free(time);
	free(space);
    }

    dx = 2*SF_PI/(2*kiss_fft_next_fast_size(nx-1)*dx);
    dw = 16*SF_PI/(d2*n3); /* 2pi * 8 */

    stack = sf_floatalloc3(n1,nx,nv);
    stack2 = sf_floatalloc3(n1,nx,nv);
    cont = sf_floatalloc3(n1,nx,nv);
    image = sf_floatalloc2(n1,nx);
    trace = sf_floatalloc(n1);
    strace = sf_floatalloc(n3);
    ctrace = sf_complexalloc(nw);
    ctrace0 = sf_complexalloc(nw);

    if (!sf_getint("extend",&next)) next=4;
    /* trace extension */
    str = fint1_init(next,n1,0);
    istr = fint1_init(next,n2,0);

    for (i1=0; i1 < n1*nx*nv; i1++) {
	stack[0][0][i1] = 0.;
	stack2[0][0][i1] = 0.;
    }

    sf_cosft_init(nx);

    for (ih=0; ih < nh; ih++) {
	sf_warning("offset %d of %d;",ih+1,nh);

	h = h0 + ih*dh;
	h *= h * 0.5;

	sf_floatread(image[0],n1*nx,in);

	for (i1=0; i1 < n1; i1++) {
	    sf_cosft_frw(image[0],i1,n1);
	}

	for (ix=0; ix < nx; ix++) {
	    x = ix*dx; 
	    x *= x;

	    k = x * 0.5;

	    fint1_set(str,image[ix]);

	    for (i2=0; i2 < n2; i2++) {
		t = o2+i2*d2;
		t = sqrtf(t);
		t = (t-o1)/d1;
		i1 = t;
		if (i1 >= 0 && i1 < n1) {
		    strace[i2] = fint1_apply(str,i1,t-i1,false);
		} else {
		    strace[i2] = 0.;
		}
	    }

	    for (i2=n2; i2 < n3; i2++) {
		strace[i2] = 0.;
	    }

	    kiss_fftr(forw,strace, (kiss_fft_cpx *) ctrace0);   

	    for (iv=0; iv < nv; iv++) {
		v = v0 + (iv+1)* dv;

		v1 = h * (1./(v*v) - 1./(v0*v0));
		v2 = k * ((v0*v0) - (v*v));

		ctrace[0]=sf_cmplx(0.,0.); /* dc */

		for (i2=1; i2 < nw; i2++) {
		    w = i2*dw;
		    w = v2/w+(v1-0.125*o2)*w;
		    shift = sf_cmplx(cosf(w),sinf(w));

#ifdef SF_HAS_COMPLEX_H
		    ctrace[i2] = ctrace0[i2] * shift;
#else
		    ctrace[i2] = sf_cmul(ctrace0[i2],shift);
#endif
		} /* w */

		kiss_fftri(invs,(const kiss_fft_cpx *) ctrace, strace);
		
		fint1_set(istr,strace);
		
		for (i1=0; i1 < n1; i1++) {
		    t = o1+i1*d1;
		    t = t*t;
		    t = (t-o2)/d2;
		    i2 = t;
		    if (i2 >= 0 && i2 < n2) {
			cont[iv][ix][i1] = fint1_apply(istr,i2,t-i2,false);
		    } else {
			cont[iv][ix][i1] = 0.;
		    }
		}
	    } /* v */
	} /* x */

	for (iv=0; iv < nv; iv++) {
	    for (i1=0; i1 < n1; i1++) {
		sf_cosft_inv(cont[0][0],i1+iv*nx*n1,n1);
	    }
	}

	for (iv=0; iv < nv; iv++) {
	    for (ix=0; ix < nx; ix++) {
		for (i1=0; i1 < n1; i1++) {	
		    t = cont[iv][ix][i1];
		    stack[iv][ix][i1] += t;
		    stack2[iv][ix][i1] += t*t;
		} /* i1 */
	    } /* x */
        } /* v */
    } /* h */
    sf_warning(".");

    for (iv=0; iv < nv; iv++) {
	for (ix=0; ix < nx; ix++) {
	    for (i1=0; i1 < n1; i1++) {
		ib = i1-nb > 0? i1-nb: 0;
		ie = i1+nb+1 < n1? i1+nb+1: n1;

		    num = 0.;
		    den = 0.;

		if (sembl) {

		    for (i2=ib; i2 < ie; i2++) {
			t = stack[iv][ix][i2];
			num += t*t;
			den += stack2[iv][ix][i2];
		    }
		    
		    den *= nh;
		    
		    trace[i1] = den > 0.? num/den: 0.;
		} else {

		    for (i2=ib; i2 < ie; i2++) {
			t = stack[iv][ix][i2];
			num += t;
		    }

		    den = nh;
		    trace[i1] =  num/(den+ FLT_EPSILON);
		}
	    }
	    sf_floatwrite (trace,n1,out);
	}
    }

    exit(0);
}
Beispiel #28
0
int main(int argc, char *argv[])
{
    int n1;			/* number of samples in input trace	 */
    int n1w;		/* number of samples in time window      */
    int N1w;	       	/* number of time windows		*/
    int n1ws;	       	/* number of samples in window (wo taper)*/
    int n1wf;	       	/* number of samples in first window     */
    int n1wi;	       	/* number of samples in intermed. window */
    int n1taper;	       	/* number of samples in taper		*/
    int n2;	       		/* number of input traces		*/
    int n3;	       		/* number of input sections		*/
    int n2w;	       	/* number of traces in window		*/
    int N2w;	       	/* number of spacial windows		*/
    int n2wu;	       	/* updated number of traces in window	*/
    int nfft;		/* transform length			*/
    int nf;			/* number of frequencies		*/
    int lenf;		/* number of traces for filter		*/
    int i2w,i2,jr,itt;	/* summation indexes			*/
    int i1,i3,i1w,ifq,ir;	/* summation indexes			*/
    int ig,ifv;		/* summation indexes			*/
    bool verb;		/* flag to get advisory messages	*/
    int *ipvt;		/* indices of pivot permutations	*/

    float *info;		/* index of last zero pivot		*/
    float dt;		/* sampling interval in secs		*/
    float df;		/* sample interval in Hz		*/
    float fmin;		/* minimum frequency to process in Hz	*/
    float fmax;		/* maximum frequency to process in Hz	*/
    float taper;		/* length of taper			*/
    float twlen;       	/* time window length 			*/
    float **tracein;      	/* real trace			   	*/
    float **traceout;     	/* real trace			   	*/
    float *traceintw;       /* real trace in time window - input   	*/
    float *traceinttw;      /* real trace in time window - input   	*/
    float *traceotw;       	/* real trace in time window - output   */
    float *traceottw;      	/* real trace in time window - output   */
    float *rauto;       	/* real part of autocorrelation   	*/
    float *iauto;       	/* imaginary part of autocorretation 	*/
    float **cautom;      	/* complex autocorrelation matrix	*/
    float *aav;       	/* advanced autocorrelation vector	*/

    kiss_fft_cpx *cdata;	/* complex transformed trace (window)  	*/
    kiss_fft_cpx **fdata;	/* data - freq. domain          	*/
    kiss_fft_cpx **fdataw;	/* data - freq. domain - in window     	*/
    kiss_fft_cpx *sfv;	/* single frequency vector 	  	*/
    kiss_fft_cpx **ffv;	/* filtered frequency vector 	  	*/
    kiss_fft_cpx *fv;	/* frequency vector		      	*/
    kiss_fft_cpx *sfvout;	/* single frequency output vector      	*/
    kiss_fft_cpx *sfvcj;	/* complex conjugate of sfv	  	*/
    kiss_fft_cpx *acorr;	/* autocorrelation output	  	*/
    kiss_fft_cpx *filter;	/* filter               	  	*/

    kiss_fftr_cfg forw, invs;
    sf_file in, out;

    sf_init(argc,argv);

    in = sf_input("in");
    out = sf_output("out");

    if(!sf_getbool("verb",&verb)) verb=false;
    /* flag to get advisory messages */
	
    if(!sf_histint(in, "n1", &n1))  sf_error("No n1 in input");  if (verb) sf_warning("n1 = %i",n1);
    if(!sf_histfloat(in, "d1", &dt)) sf_error("No d1 in input"); if (verb) sf_warning("dt= %f",dt);
    if(!sf_histint(in,"n2",&n2))   sf_error("No n2 in input");   if (verb) sf_warning("n2= %f",n2);
    if(!sf_histint(in,"n3",&n3))   n3=1; if (verb) sf_warning("n3= %f",n3);

    if(!sf_getfloat("taper",&taper)) taper=.1;
    /* length of taper */
    if (taper==0.0) taper=.004; 

    if(!sf_getfloat("fmin",&fmin)) fmin=1.;    
    /* minimum frequency to process in Hz */
    if (fmin==0.0)  if (verb) sf_warning("using fmin=1 Hz");

    if(!sf_getfloat("fmax",&fmax)) fmax=1./(2*dt); 
    /* maximum frequency to process in Hz */
    if (fmax==0.0) if (verb) sf_warning("using fmax=1/(2*dt) Hz");

    if (!sf_getfloat("twlen", &twlen)) twlen=(float)(n1-1)*dt;
    /* time window length */
    if (twlen<.3) {
	twlen=.3; if (verb) sf_warning("twlen cannot be less than .3s, using .3s");
    }
    /* setting taper and spatial and temporal windows */
    n1taper =roundf(taper/dt);
    n1taper = (n1taper%2 ? n1taper+1 : n1taper); 

    N1w = roundf((n1-1)*dt/twlen);

    if (N1w==1) taper=0.0;

    n1ws = roundf(twlen/dt) + 1;
    n1wf = n1ws + n1taper/2;
    n1wi = n1ws + n1taper;

    if (!sf_getint("n2w", &n2w)) n2w=10;
    /* number of traces in window */
    if (!n2w) {
	n2w = 10;
	if (verb) sf_warning("n2w cannot be zero, using 10 traces");
    }	
    if (verb) sf_warning("n2w = %i",n2w);

    n2wu = n2w;

    if (!sf_getint("lenf", &lenf)) lenf=4; 
    /* number of traces for filter */
    if (!lenf) if (verb) sf_warning("using lenf=4");	
	
    N2w = n2/n2w;

    /* Computute FFT optimization number */
    nfft = 2*kiss_fft_next_fast_size((n1wf+1)/2);

    forw = kiss_fftr_alloc(nfft,0,NULL,NULL);
    invs = kiss_fftr_alloc(nfft,1,NULL,NULL);

    nf = nfft/2 + 1;
    df = 1.0/(nfft*dt);

    /* space allocation */
    cdata 	= (kiss_fft_cpx*) sf_complexalloc(nfft);
    traceintw =sf_floatalloc(nfft);
    traceinttw=sf_floatalloc(nfft);
    fdata   =(kiss_fft_cpx**) sf_complexalloc2(nf,n2);
    fdataw  =(kiss_fft_cpx**) sf_complexalloc2(nf,2*n2w+2*lenf);
    tracein = sf_floatalloc2(n1,n2);
    traceout= sf_floatalloc2(n1,n2);
    sfv   = (kiss_fft_cpx*) sf_complexalloc(2*n2w+2*lenf);
    sfvcj = (kiss_fft_cpx*) sf_complexalloc(2*n2w+2*lenf);
    acorr= (kiss_fft_cpx*) sf_complexalloc(lenf+1);
    rauto  = sf_floatalloc(lenf+1);
    iauto  = sf_floatalloc(lenf+1);
    cautom = sf_floatalloc2(2*lenf,2*lenf);
    aav = sf_floatalloc(2*lenf);
    filter = (kiss_fft_cpx*) sf_complexalloc(2*lenf+1);
    ffv   = (kiss_fft_cpx**) sf_complexalloc2(nf,2*n2w);
    sfvout=(kiss_fft_cpx*) sf_complexalloc(2*n2w);
    fv   =(kiss_fft_cpx*) sf_complexalloc(nfft);
    traceotw = sf_floatalloc(nfft);
    traceottw= sf_floatalloc(nfft);
    ipvt 	= sf_intalloc(4*n2w);
    info	= sf_floatalloc(4*n2w);

    /* zero output file */
    memset((void *) traceout[0], 0, n2*n1*sizeof(float));


    for (i3=0;i3<n3;i3++)
    {
    /* load traces into the zero-offset array and close tmpfile */
    sf_floatread(tracein[0],n1*n2,in);	
	
    /* If dt not set, issue advisory on frequency step df */
    if (dt && verb) sf_warning("df=%f", 1.0/(nfft*dt));

    if (verb) sf_warning("nf=%i, df=%f, nfft=%i, n1taper=%i", nf,df,nfft,n1taper);

    /* loop over time windows */
    for (i1w=0;i1w<N1w;i1w++) {

	if (i1w>0 && i1w<N1w-1) n1w=n1wi; 
	else if (i1w==0) 
	    if (N1w>1) n1w = n1wf;
	    else        n1w = n1;
	else
	    n1w = n1 - n1ws*i1w + n1taper/2;
 
	if (verb) sf_warning("i1w=%i, N1w=%i, n1w=%i, twlen=%f", i1w,N1w,n1w,twlen); 

	/* zero fdata */
	memset((void *) fdata[0], 0, nf*n2*sizeof(kiss_fft_cpx));
     
	/* select data */
	for (i2=0;i2<n2;i2++) {
 
	    if (i1w>0)
		for (i1=0;i1<n1w;i1++)
		    traceintw[i1]=tracein[i2][i1 + i1w*n1ws - n1taper/2];
	    else
		for (i1=0;i1<n1w;i1++)  
		    traceintw[i1]=tracein[i2][i1];	  

	    memset((void *) (traceintw + n1w), 0, (nfft-n1w)*sizeof(float));
	    memset((void *) cdata, 0, nfft*sizeof(kiss_fft_cpx));

	    /* FFT from t to f */
	    for (i1=0;i1<nfft;i1++)
		traceinttw[i1]=(i1%2 ? -traceintw[i1] : traceintw[i1]);
	    kiss_fftr(forw, traceinttw, cdata);

	    /* Store values */    
	    for (ifq = 0; ifq < nf; ifq++) { 
		fdata[i2][ifq] = cdata[nf-1-ifq];
	    }
	}

	/* Loop over space windows */
	for (i2w=0;i2w<N2w;i2w++){

	    /* to take care of a possible incomplete last window */
	    if (n2<i2w*n2w+2*n2w) 
		n2wu = n2 - i2w*n2w;
	    else
		n2wu = n2w;

	    if (verb) {
		sf_warning("i2w=%i, n2=%i, n2w=%i",
			   i2w,n2,n2w);
		sf_warning("n2wu=%i, N2w=%i, lenf=%i",
			   n2wu,N2w,lenf);
	    }

	    /* zero fdataw */
	    for (i2=0;i2<n2w+2*lenf;i2++)
		memset((void *) fdataw[i2], 0, nf*sizeof(kiss_fft_cpx));

	    /* select data */
	    for (i2=0;i2<n2wu+2*lenf;i2++) 
		for (ifq = 0; ifq < nf; ifq++) {

		    if (i2w>0 && i2w<N2w-1)  
			fdataw[i2][ifq] = fdata[i2 + i2w*n2w - lenf][ifq];
		    else if (i2w==0)
			if (i2>=lenf && i2<n2w+lenf) 
			    fdataw[i2][ifq] = fdata[i2 - lenf][ifq];
			else if (i2<lenf) 
			    fdataw[i2][ifq] = fdata[0][ifq];
			else 
			    if (N2w>1) 
				fdataw[i2][ifq] = fdata[i2 - lenf][ifq];
			    else 
				fdataw[i2][ifq] = fdata[n2-1][ifq];
		    else
			if (i2<n2wu+lenf)
			    fdataw[i2][ifq] = fdata[i2 + i2w*n2w - lenf][ifq];
			else 
			    fdataw[i2][ifq] = fdata[n2-1][ifq];
		}

	    /* loop over frequencies */
	    for (ifq=0;ifq<nf;ifq++) {

		if ((float)ifq*df>=fmin && (float)ifq*df<=fmax) {

		    /* Loop over space window */
		    memset((void *) sfv, 0, (n2wu+2*lenf)*sizeof(kiss_fft_cpx));
		    memset((void *) sfvcj, 0, (n2wu+2*lenf)*sizeof(kiss_fft_cpx));

		    for (i2=0;i2<n2wu+2*lenf;i2++) {
	  
			sfv[i2]=fdataw[i2][ifq];
			sfvcj[i2]=sf_conjf(fdataw[i2][ifq]);
		    }

		    memset((void *) acorr, 0, (lenf+1)*sizeof(kiss_fft_cpx));

		    /* complex autocorrelation */
		    cxcor(n2wu,0,sfv,n2wu,0,sfv,lenf+1,0,acorr);

		    /* zeroing files */
		    memset((void *) rauto, 0, (lenf+1)*sizeof(float));
		    memset((void *) iauto, 0, (lenf+1)*sizeof(float));

		    /* taking real and imaginary parts */
		    for (i2=0;i2<lenf+1;i2++) {
			rauto[i2]=acorr[i2].r;
			iauto[i2]=acorr[i2].i;
		    }

		    /* zeroing files */
		    memset((void *) aav, 0, 2*lenf*sizeof(float));
		    memset((void *) filter, 0, (2*lenf+1)*sizeof(kiss_fft_cpx));
		    for (ir=0;ir<2*lenf;ir++) 
			memset((void *) cautom[ir], 0, 2*lenf*sizeof(float));

		    /* matrix problem */
		    for (ir=0;ir<lenf;ir++) 
			for (jr=0;jr<lenf;jr++) { 
			    if (ir>=jr) cautom[ir][jr]=acorr[ir-jr].r;
			    else        cautom[ir][jr]=acorr[jr-ir].r;
			}

		    for (ir=lenf;ir<2*lenf;ir++)
			for (jr=0;jr<lenf;jr++) {
			    if (ir-lenf<jr) cautom[ir][jr]=-acorr[jr-ir+lenf].i;
			    else            cautom[ir][jr]= acorr[ir-jr-lenf].i;
			}

		    for (ir=lenf;ir<2*lenf;ir++)
			for (jr=lenf;jr<2*lenf;jr++)
			    cautom[ir][jr]=cautom[ir-lenf][jr-lenf];

		    for (ir=0;ir<lenf;ir++)
			for (jr=lenf;jr<2*lenf;jr++)
			    cautom[ir][jr]=-cautom[ir+lenf][jr-lenf];

		    for (ig=0;ig<2*lenf;ig++) {
			if (ig<lenf) aav[ig]=acorr[ig+1].r;
			else aav[ig]=acorr[ig-lenf+1].i;
		    }

		    lu_decomposition(2*lenf,cautom,ipvt,info);
		    backward_substitution(2*lenf,cautom,ipvt,aav);
      
		    /* construct filter */
		    for (ifv=0,ig=lenf-1;ifv<lenf;ifv++,ig--) 
			filter[ifv]=sf_conjf(cmplx(aav[ig]/2.,aav[ig+lenf]/2.));

		    for (ifv=lenf+1,ig=0;ifv<2*lenf+1;ifv++,ig++) 
			filter[ifv]=cmplx(aav[ig]/2.,aav[ig+lenf]/2.);
	 
		    memset((void *) sfvout, 0, n2wu*sizeof(kiss_fft_cpx));

		    /* convolution of data with filter */
		    /* output is one sample ahead */
		    cconv(n2wu+2*lenf,-lenf,sfv,2*lenf+1,-lenf,filter,n2wu,0,sfvout); 

		    /* store filtered values */
		    for (i2=0;i2<n2wu;i2++) ffv[i2][ifq]=sfvout[i2];

		}
	    } /* end of frequencies loop */

	    /* loop along space windows */
	    for (i2=0;i2<n2wu;i2++) {
    
		/* select data */
		for (ifq=0,itt=nf-1;ifq<nf;ifq++,itt--)
		    fv[ifq] = ffv[i2][itt]; 

		memset((void *) (fv+nf), 0, (nfft-nf)*sizeof(kiss_fft_cpx));
		memset((void *) traceotw, 0, nfft*sizeof(float));

		/* FFT back from f to t and scaling */
		kiss_fftri(invs,fv,traceotw);
		for (i1=0;i1<SF_MIN(n1,nfft);i1++)
		    traceotw[i1]/=nfft; 
		for (i1=0;i1<SF_MIN(n1,nfft);i1++)
		    traceottw[i1]=(i1%2 ? -traceotw[i1] : traceotw[i1]); 
      
		/*loop along time */
		if (N1w>1) {
		    /* first portion of time window */
		    if (i1w>0) 
			for (i1=0;i1<n1taper;i1++)
			    traceout[i2w*n2w+i2][i1+i1w*n1ws-n1taper/2]+=
				traceottw[i1]*((float)(i1)*dt/taper);
		    else 
			for (i1=0;i1<n1taper;i1++)
			    traceout[i2w*n2w+i2][i1]=traceottw[i1];

		    /* intermediate portion of time window */
		    if (i1w>0) 
			for (i1=n1taper;i1<n1w-n1taper;i1++)
			    traceout[i2w*n2w+i2][i1+i1w*n1ws-n1taper/2]=traceottw[i1];
		    else 
			for (i1=n1taper;i1<n1w-n1taper;i1++)
			    traceout[i2w*n2w+i2][i1]=traceottw[i1];

		    /* last portion of time window */
		    if (i1w>0 && i1w<N1w-1) 
			for (i1=n1w-n1taper;i1<n1w;i1++)
			    traceout[i2w*n2w+i2][i1+i1w*n1ws-n1taper/2]+=
				traceottw[i1]*(1.-((float)(i1-n1w+n1taper))*dt/taper);
		    else if (i1w==N1w-1)
			for (i1=n1w-n1taper;i1<n1w;i1++)
			    traceout[i2w*n2w+i2][i1+i1w*n1ws-n1taper/2]=traceottw[i1];
		    else 
			for (i1=n1w-n1taper;i1<n1w;i1++)
			    traceout[i2w*n2w+i2][i1]+=traceottw[i1]*(1.-((float)(i1-n1w+n1taper))*dt/taper);
		}
		else {
		    for (i1=0;i1<n1;i1++) 
			traceout[i2w*n2w+i2][i1]=traceottw[i1];
		}

	    } /* end loop over space windows */

	} /* end loop over space windows */

    } /* end of time windows loop */
 
    /* Write output data to file */
    sf_floatwrite(traceout[0], n1*n2, out);
    if(verb) sf_warning("I3=%d is done!\n",i3+1);
    }

    /* Free allocated memory */
    free(traceintw);
    free(traceinttw);
    free(fdataw[0]);
    free(fdataw);
    free(sfv);
    free(sfvcj);
    free(acorr);
    free(rauto);
    free(iauto);
    free(cautom[0]);
    free(cautom);
    free(aav);
    free(filter);
    free(sfvout);
    free(fv);
    free(traceotw);
    free(traceottw);
    free(ffv[0]);
    free(ffv);
    free(tracein[0]);
    free(tracein);
    free(traceout[0]);
    free(traceout);

    exit(0);
}
int main(int argc, char ** argv)
{
    int k;
    int nfft[32];
    int ndims = 1;
    int isinverse = 0;
    int numffts = 1000, i;
    kiss_fft_cpx * buf;
    kiss_fft_cpx * bufout;
    int real = 0;

    nfft[0] = 1024;// default

    while (1) {
        int c = getopt(argc, argv, "n:ix:r");
        if (c == -1)
            break;
        switch (c) {
        case 'r':
            real = 1;
            break;
        case 'n':
            ndims = getdims(nfft, optarg);
            if (nfft[0] != kiss_fft_next_fast_size(nfft[0])) {
                int ng = kiss_fft_next_fast_size(nfft[0]);
                fprintf(stderr, "warning: %d might be a better choice for speed than %d\n", ng, nfft[0]);
            }
            break;
        case 'x':
            numffts = atoi(optarg);
            break;
        case 'i':
            isinverse = 1;
            break;
        }
    }
    int nbytes = sizeof(kiss_fft_cpx);
    for (k = 0; k < ndims; ++k)
        nbytes *= nfft[k];

#ifdef USE_SIMD
    numffts /= 4;
    fprintf(stderr, "since SIMD implementation does 4 ffts at a time, numffts is being reduced to %d\n", numffts);
#endif

    buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes);
    bufout = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes);
    memset(buf, 0, nbytes);

    pstats_init();

    if (ndims == 1) {
        if (real) {
            kiss_fftr_cfg st = kiss_fftr_alloc(nfft[0] , isinverse , 0, 0);
            if (isinverse)
                for (i = 0; i < numffts; ++i)
                    kiss_fftri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout);
            else
                for (i = 0; i < numffts; ++i)
                    kiss_fftr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout);
            free(st);
        } else {
            kiss_fft_cfg st = kiss_fft_alloc(nfft[0] , isinverse , 0, 0);
            for (i = 0; i < numffts; ++i)
                kiss_fft(st , buf, bufout);
            free(st);
        }
    } else {
        if (real) {
            kiss_fftndr_cfg st = kiss_fftndr_alloc(nfft, ndims , isinverse , 0, 0);
            if (isinverse)
                for (i = 0; i < numffts; ++i)
                    kiss_fftndri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout);
            else
                for (i = 0; i < numffts; ++i)
                    kiss_fftndr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout);
            free(st);
        } else {
            kiss_fftnd_cfg st = kiss_fftnd_alloc(nfft, ndims, isinverse , 0, 0);
            for (i = 0; i < numffts; ++i)
                kiss_fftnd(st , buf, bufout);
            free(st);
        }
    }

    free(buf); free(bufout);

    fprintf(stderr, "KISS\tnfft=");
    for (k = 0; k < ndims; ++k)
        fprintf(stderr, "%d,", nfft[k]);
    fprintf(stderr, "\tnumffts=%d\n" , numffts);
    pstats_report();

    kiss_fft_cleanup();

    return 0;
}
Beispiel #30
0
void fft1 (float *field, float *Field, sf_file in, bool inv, bool sym, bool opt)
/*< Fast Fourier Transform along the first axis >*/
{
    /*bool inv, sym, opt;*/
    int n1, nt, nw, i1, i2, n2;
    float dw, *p, d1, o1, wt, shift;
    kiss_fft_cpx *pp, ce;
    char *label;
    sf_file out=NULL;
    kiss_fftr_cfg cfg;
	bool verb;

	verb=1;

	if (verb) fprintf(stderr,"Beginning of fft1. inv:%d sym: %d opt:%d \n",inv,sym,opt);
    
	/*sf_init(argc, argv);
    in  = sf_input("in");
    out = sf_output("out");*/

    /*if (!sf_getbool("inv",&inv)) inv=false;*/
    /* if y, perform inverse transform */
    /*if (!sf_getbool("sym",&sym)) sym=false;*/
    /* if y, apply symmetric scaling to make the FFT operator Hermitian */
    /*if (!sf_getbool("opt",&opt)) opt=true;*/
    /* if y, determine optimal size for efficiency */
	
    
	if (inv) {
	if (SF_COMPLEX != sf_gettype(in)) sf_error("Need complex input");
	/*sf_settype (out,SF_FLOAT);*/
    } else {
	if (SF_FLOAT   != sf_gettype(in)) sf_error("Need float input");
    	/*sf_settype (out,SF_COMPLEX);*/
    }

    n2 = sf_leftsize(in,1);

    if (!inv) {
	if (!sf_histint  (in,"n1",&n1)) n1=1;
	if (!sf_histfloat(in,"d1",&d1)) d1=1.;
	if (!sf_histfloat(in,"o1",&o1)) o1=0.;

	if (verb) fprintf(stderr,"n1: %d n2: %d nt: %d nw: %d dw:%f o1:%f\n",n1,n2,nt,nw,dw,o1);
	/* determine wavenumber sampling (for real to complex FFT) */
	nt = opt? 2*kiss_fft_next_fast_size((n1+1)/2): n1;
	if (nt%2) nt++;
	nw = nt/2+1;
	dw = 1./(nt*d1);
  sf_warning(" Fil NW=%d dw=%g d1=%g",nw,dw,d1);


	if (verb) fprintf(stderr,"n1: %d n2: %d nt: %d nw: %d d1: %f dw:%f o1:%f\n",n1,n2,nt,nw,d1,dw,o1);

	/*sf_putint  (out,"n1",nw);
	sf_putfloat(out,"o1",0.);
	sf_putfloat(out,"d1",dw);

	sf_putfloat(out,"fft_o1",o1);
	sf_putfloat(out,"fft_n1",n1);*/

	/* fix label */
	/*if (NULL != (label = sf_histstring(in,"label1"))) {
	    sf_putstring(out,"fft_label1",label);
	    if (!sf_fft_label(1,label,out))
		sf_putstring(out,"label1","Wavenumber");
	}*/
    } else {
	if (!sf_histint  (in,"n1",&nw)) sf_error("No n1= in input");
	if (!sf_histfloat(in,"d1",&dw)) sf_error("No d1= in input");
	if (!sf_histfloat(in,"fft_o1",&o1)) o1=0.; 

	nt = 2*(nw-1);
	d1 = 1./(nt*dw);

	if (!opt || !sf_histint  (in,"fft_n1",&n1)) n1 = nt;
	
	if (verb) fprintf(stderr,"n1: %d n2: %d nt: %d nw: %d d1: %f dw:%f o1:%f\n",n1,n2,nt,nw,d1,dw,o1);
	
	/*sf_putint  (out,"n1",n1);
	sf_putfloat(out,"d1",d1);
	sf_putfloat(out,"o1",o1);*/

	/* fix label */
	/*if (NULL != (label = sf_histstring(in,"fft_label1"))) {
	    sf_putstring(out,"label1",label);
	} else if (NULL != (label = sf_histstring(in,"label1"))) {
	    (void) sf_fft_label(1,label,out);
	}*/

    }	
    
	/*sf_fft_unit(1,sf_histstring(in,"unit1"),out);*/

    p = sf_floatalloc(nt);
    pp = (kiss_fft_cpx*) sf_complexalloc(nw);

    cfg = kiss_fftr_alloc(nt,inv?1:0,NULL,NULL);
    wt = sym? 1./sqrtf((float) nt): 1.0/nt;

    
  sf_warning("inv=%d wt=%g n1=%d nt=%d nw=%d ot=%g",1,wt,n1,nt,nw,ot);







	for (i2=0; i2 < n2; i2++) {
	if (!inv) {
	    /*sf_floatread (p,n1,in);*/
	    memcpy(p,&field[i2*n1],n1*sizeof(float));

	    if (sym) {
		for (i1=0; i1 < n1; i1++) {
		    p[i1] *= wt;
		}
	    }

	    for (i1=n1; i1 < nt; i1++) {
		p[i1]=0.0;
	    }
	    kiss_fftr (cfg,p,pp);

	    if (0. != o1) {
		for (i1=0; i1 < nw; i1++) {
		    shift = -2.0*SF_PI*i1*dw*o1;
		    ce.r = cosf(shift);
		    ce.i = sinf(shift);
		    pp[i1]=sf_cmul(pp[i1],ce);
		}
	    }
		
		memcpy(&Field[i2*2*nw],pp,2*nw*sizeof(float));

	    /*sf_floatwrite((float*) pp,2*nw,out);*/
	} else {
	    /*sf_floatread((float*) pp,2*nw,in);*/
		memcpy(pp,&field[i2*2*nw],2*nw*sizeof(float));

	    if (0. != o1) {
		for (i1=0; i1 < nw; i1++) {
		    shift = +2.0*SF_PI*i1*dw*o1;
		    ce.r = cosf(shift);
		    ce.i = sinf(shift);
		    pp[i1]=sf_cmul(pp[i1],ce);
		}
	    }

	    kiss_fftri(cfg,pp,p);

	    for (i1=0; i1 < n1; i1++) {
		p[i1] *= wt;
	    }

		memcpy(&Field[i2*n1],p,n1*sizeof(float));
	    /*sf_floatwrite (p,n1,out);*/
	}
    }

	free(p);
	free(pp);

    
	/*exit (0);*/
}