Example #1
0
void __TFWT2D_TransformerRep::init_kernel(float *pkrnl, long nkrows, long nkcols)
{
  // should never happen... but disallow kernel sizes larger
  // than the expected image size. Even though we could theoretically
  // accommodate to the ceiling power of two in size that would destroy
  // the zero fill needed for user image padding...

  check_valid_transformer();
  
  if(nkcols > m_nucols || nkrows > m_nurows)
    throw("TFWT2D_Transformer: kernel size too large.");

  VDSP_CRITICAL_SECTION {
    // prep output buffer for this run
    setup_split_complex_outbuf();
    
    // just move the kernel into the input buffer without regard
    // for its phase center. We will correct afterward.
    implant_kernel(pkrnl, nkcols, nkrows);
    
    // perform the forward FFT of the kernel
    fwd_fft();
    
    // Correct the phase center. We only nead real-valued amplitudes.
    // Prep for use as an element-by-element real-real vector multipy
    // this uses a bit more memory but it is faster in the face of the
    // 2-D packed output format of the real-to-complex FFT
    
    // first get back to packed format from this wierd output format provided
    ztoc(&m_outdata, 1, m_pkrnlmask, 2, m_tsize2);
    
    // then, for each row and every complex column except the first...
    for(long iy = m_nirows; --iy >= 0; )
      {
	long off = iy * m_nicols2;
	for(long ix = m_nicols2; --ix > 0; )
	  {
	    long   k  = off + ix;
	    double re = (double)m_pkrnlmask[k].real;
	    double im = (double)m_pkrnlmask[k].imag;
	    float v   = (float)hypot(re,im);
	    (*m_poutbuf)[k].real = v;
	    (*m_poutbuf)[k].imag = v;
	  }
      }
    // Then in the first complex column, for all rows except the first two...
    float *pdst = *(float**)m_poutbuf;
    float *psrc = (float*)m_pkrnlmask;
    for(long iy = 2; iy < m_nirows; iy += 2)
      {
	long kre = iy*m_nicols;
	long kim = kre + m_nicols;
	double re = (double)psrc[kre];
	double im = (double)psrc[kim];
	float v   = (float)hypot(re,im);
	pdst[kre] = v;
	pdst[kim] = v;
	
	++kre;
	++kim;
	re = psrc[kre];
	im = psrc[kim];
	v = (float)hypot(re,im);
	pdst[kre] = v;
	pdst[kim] = v;
      }
    // finally, copy over the remaining untouched 4 cells
    for(long iy = 2; --iy >= 0;)
      {
	long off = iy * m_nicols;
	for(long ix = 2; --ix >= 0;)
	  {
	  long k = ix + off;
	  pdst[k] = psrc[k];
	  }
      }
    // now refold the kernel so that we can do straight multiplies in the filter
    DSPSplitComplex kdata = {(float*)m_pkrnlmask,
			     (float*)m_pkrnlmask + m_tsize2};
    ctoz(*m_poutbuf, 2, &kdata, 1, m_tsize2);

  } END_VDSP_CRITICAL_SECTION;

  // apply descaling for round-trip amplification
  // = *2 for forward FFT on image
  // = *tsize for inverse FFT on image
  // = *2 for forward FFT on kernel
  long tsize = m_nicols * m_nirows;
  float sf = 0.25/tsize;
  
  vsmul((const float*)m_pkrnlmask, 1, &sf,
	(float*)m_pkrnlmask, 1, tsize);
}
Example #2
0
void noisiness_tick_G4(t_noisiness *x) {

    t_int i, index=0, cpt;
    t_float Spz = 0.0f, SFM = 0.0f;
    double prod = 1.0f, sum = 0.0f;
    double invNumBand = 0.04f;

    // Zero padding
    for (i=x->BufSize; i<x->FFTSize; i++)
        x->BufFFT[i] = 0.0f;

    // Window the samples
    if (x->x_window != Recta)
        for (i=0; i<x->BufSize; ++i)
            x->BufFFT[i] *= x->WindFFT[i];

    // Look at the real signal as an interleaved complex vector by casting it.
    // Then call the transformation function ctoz to get a split complex vector,
    // which for a real signal, divides into an even-odd configuration.
    ctoz ((COMPLEX *) x->BufFFT, 2, &x->x_A, 1, x->x_FFTSizeOver2);

    // Carry out a Forward FFT transform
    fft_zrip(x->x_setup, &x->x_A, 1, x->x_log2n, FFT_FORWARD);

    // The output signal is now in a split real form.  Use the function
    // ztoc to get a split real vector.
    ztoc ( &x->x_A, 1, (COMPLEX *) x->BufFFT, 2, x->x_FFTSizeOver2);

    // Squared Absolute
    for (i=0; i<x->FFTSize; i+=2)
        x->BufFFT[i/2] = (x->BufFFT[i] * x->BufFFT[i]) + (x->BufFFT[i+1] * x->BufFFT[i+1]);

    // Band Spz
    for (i=0; i<NUMBAND; i++) {
        cpt = x->BufSizeBark[i];
        Spz = 0.0f;
        while (cpt > 0) {
            Spz += x->BufFFT[index];
            cpt--;
            index++;
        }
        Spz = Spz/x->BufSizeBark[i];

        sum += Spz;
        prod *= Spz;
    }

    prod = pow(prod,invNumBand);
    sum  = invNumBand * sum;
    SFM = prod/sum;

    // Spectral Flatness Measure (SFM)
    if (SFM > 0) {
        SFM = 10*log10(prod/sum);
    } else {
        SFM = 0.0f;
    }

    // Tonality factor or Peakiness
    x->x_noisiness = MINF((SFM/-SFM_MAX),1); // minimum of both

    // Output result
    outlet_float(x->x_outnois, (1.0 - x->x_noisiness));
}
Example #3
0
void pitch_tick_G4(t_pitch *x) {

	t_int halfFFTSize = x->FFTSize/2;
	t_float FsOverFFTSize = x->x_Fs/((t_float)x->FFTSize);
    t_pitchhist *ph;
	t_int i;
		
	// Zero padding
	for (i=x->BufSize; i<x->FFTSize; i++)
		x->BufFFT[i] = 0.0f;

	// Window the samples
	if (x->x_window != Recta)
		for (i=0; i<x->BufSize; ++i)
			x->BufFFT[i] *= x->WindFFT[i];
			
    // Look at the real signal as an interleaved complex vector by casting it.
    // Then call the transformation function ctoz to get a split complex vector,
    // which for a real signal, divides into an even-odd configuration.
    ctoz ((COMPLEX *) x->BufFFT, 2, &x->x_A, 1, x->x_FFTSizeOver2);
      
    // Carry out a Forward FFT transform
    fft_zrip(x->x_setup, &x->x_A, 1, x->x_log2n, FFT_FORWARD);

	// Fast rescaling required
//    vsmul( x->x_A.realp, 1, &x->x_scaleFactor, x->x_A.realp, 1, x->x_FFTSizeOver2);
//    vsmul( x->x_A.imagp, 1, &x->x_scaleFactor, x->x_A.imagp, 1, x->x_FFTSizeOver2);

    // The output signal is now in a split real form.  Use the function
    // ztoc to get a split real vector.
    ztoc ( &x->x_A, 1, (COMPLEX *) x->BufFFT, 2, x->x_FFTSizeOver2);
		
	// Squared Absolute
	for (i=0; i<x->FFTSize; i+=2) 
		x->BufPower[i/2] = (x->BufFFT[i] * x->BufFFT[i]) + (x->BufFFT[i+1] * x->BufFFT[i+1]);
		
	// Go into fiddle~ code
	pitch_getit(x);
	
	// Output results
    if (x->x_npeakout) { // Output peaks
    	t_peakout *po;
    	for (i=0, po=x->peakBuf; i<x->x_npeakout; i++, po++) {
			t_atom at[3];
	    	atom_setlong(at, i+1);
	    	atom_setfloat(at+1, po->po_freq);
	    	atom_setfloat(at+2, po->po_amp);
	    	outlet_list(x->x_peakout, 0, 3, at);
		}
    }
  
    // Output amplitude 
    outlet_float(x->x_envout, x->x_dbs[x->x_histphase]);
    
    // Output fundamental frequencies + amplitudes
    if (x->x_npitch > 1) {
		for (i=0,  ph=x->x_hist; i<x->x_npitch; i++, ph++) {
			t_atom at[3];
			atom_setlong(at, i+1);
			atom_setfloat(at+1, ph->h_pitches[x->x_histphase]);
			atom_setfloat(at+2, ph->h_amps[x->x_histphase]);
			outlet_list(x->x_pitchout, 0, 3, at);
   		}
   	} else {
		for (i=0,  ph=x->x_hist; i<x->x_npitch; i++, ph++) {
			t_atom at[2];
			atom_setfloat(at, ph->h_pitches[x->x_histphase]);
			atom_setfloat(at+1, ph->h_amps[x->x_histphase]);
			outlet_list(x->x_pitchout, 0, 2, at);
   		}
	}   	
       
    // Output cooked MIDI/Frequency pitch
    if (x->x_npitch > 1) {
	    for (i=0, ph=x->x_hist; i<x->x_npitch; i++, ph++)
 			if (ph->h_pitch) {
				t_atom at[3];
				atom_setlong(at, i+1);
				atom_setfloat(at+1, ph->h_pitch);
				atom_setfloat(at+2, mtof(ph->h_pitch));
				outlet_list(x->x_noteout, 0, 3, at);
			}
	} else {
		ph = x->x_hist;
 		if (ph->h_pitch) {
			t_atom at[2];
			atom_setfloat(at, ph->h_pitch);
			atom_setfloat(at+1, mtof(ph->h_pitch));
			outlet_list(x->x_noteout, 0, 2, at);
		}
	}
			
    // Output attack bang 
    if (x->x_attackvalue) outlet_bang(x->x_attackout);

}