Beispiel #1
0
void CFFTOSX::GetMagnitude(sample* pfSamples) throw (IException*)
{
	// Only 32-bit sample is supported
	if (sizeof(sample) != 4) {
		throw IException::Create(IException::TypeCode,
			IException::ReasonGeneric,
			EXCEPTION_INFO,
			(tchar*)"Unknown or unsupported sample size");
	}

	// Convert to required format
	ctoz((COMPLEX*)pfSamples, 2, &mA, 1, muiFFTSize / 2);

	// FFT
	fft_zrip(mFFT, &mA, 1, muiOrder, FFT_FORWARD);

	// Scale it
	float fScale = 1.0f / (2 * muiFFTSize);
	vsmul(mA.realp, 1, &fScale, mA.realp, 1, muiFFTSize / 2);
	vsmul(mA.imagp, 1, &fScale, mA.imagp, 1, muiFFTSize / 2);
	
	// Convert to magnitude
	tint32 iIndex;
	for (iIndex = 1; iIndex < muiFFTSize / 2; iIndex++) {
		pfSamples[iIndex] = (float)sqrt((mA.realp[iIndex] * mA.realp[iIndex]) + (mA.imagp[iIndex] * mA.imagp[iIndex]));
	}
	// Special cases
	pfSamples[0] = (float)sqrt(mA.realp[0] * mA.realp[0]);
	pfSamples[muiFFTSize / 2] = (float)sqrt(mA.realp[1] * mA.realp[1]);
}
Beispiel #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));
}
Beispiel #3
0
ITunesPixelFormat ivis_render( ITunesVis* plugin, short audio_data[][512], float freq_data[][512],
                               void* buffer, long buffer_size, bool idle )
{
  ITunesPixelFormat format = ITunesPixelFormatUnknown;

  /* make sure we have a plugin and a visual handler */
  if ( !plugin || !plugin->imports.visual_handler )
    return format;

  int i=0, w=0;
  RenderVisualData visual_data;
  DSPSplitComplex splitComplex[2];
  float *data[2];

  /* perform FFT if we're not idling */
  if ( ! idle )
  {
    /* allocate some complex vars */
    for ( i = 0 ; i < 2 ; i++ )
    {
      splitComplex[i].realp = calloc( 512, sizeof(float) );
      splitComplex[i].imagp = calloc( 512, sizeof(float) );
      data[i] = calloc( 512, sizeof(float) );
    }

    /* 2 channels for spectrum and waveform data */
    visual_data.numWaveformChannels = 2;
    visual_data.numSpectrumChannels = 2;

    /* copy spectrum audio data to visual data strucure */
    for ( w = 0 ; w < 512 ; w++ )
    {
      /* iTunes visualizers expect waveform data from 0 - 255, with level 0 at 128 */
      visual_data.waveformData[0][w] = (UInt8)( (long)(audio_data[0][w]) / 128 + 128 );
      visual_data.waveformData[1][w] = (UInt8)( (long)(audio_data[1][w]) / 128 + 128 );

      /* scale to -1, +1 */
      *( data[0] + w ) = (float)(( audio_data[0][w]) / (2.0 * 8192.0) );
      *( data[1] + w ) = (float)(( audio_data[1][w]) / (2.0 * 8192.0) );
    }

    /* FFT scaler */
    float scale = ( 1.0 / 1024.0 ) ; /* scale by length of input * 2 (due to how vDSP does FFTs) */
    float nyq=0, dc=0, freq=0;

    for ( i = 0 ; i < 2 ; i++ )
    {
      /* pack data into format fft_zrip expects it */
      vDSP_ctoz( (COMPLEX*)( data[i] ), 2, &( splitComplex[i] ), 1, 256 );

      /* perform FFT on normalized audio data */
      fft_zrip( plugin->fft_setup, &( splitComplex[i] ), 1, 9, FFT_FORWARD );

      /* scale the values */
      vDSP_vsmul( splitComplex[i].realp, 1, &scale, splitComplex[i].realp, 1, 256 );
      vDSP_vsmul( splitComplex[i].imagp, 1, &scale, splitComplex[i].imagp, 1, 256 );

      /* unpack data */
      vDSP_ztoc( &splitComplex[i], 1, (COMPLEX*)( data[i] ), 2, 256 );

      /* ignore phase */
      dc = *(data[i]) = fabs( *(data[i]) );
      nyq = fabs( *(data[i] + 1) );

      for ( w = 1 ; w < 256 ; w++ )
      {
        /* don't use vDSP for this since there's some overflow */
        freq = hypot( *(data[i] + w * 2), *(data[i] + w * 2 + 1) ) * 256 * 16;
        freq = MAX( 0, freq );
        freq = MIN( 255, freq );
        visual_data.spectrumData[i][ w - 1 ] = (UInt8)( freq );
      }
      visual_data.spectrumData[i][256] = nyq;
    }

    /* deallocate complex vars */
    for ( i = 0 ; i < 2 ; i++ )
    {
      free( splitComplex[i].realp );
      free( splitComplex[i].imagp );
      free( data[i] );
    }

    /* update the render message with the new visual data and timestamp */
    plugin->visual_message.u.renderMessage.renderData = &visual_data;
    plugin->visual_message.u.renderMessage.timeStampID++;
  }

  /* update time */
  plugin->visual_message.u.renderMessage.currentPositionInMS =
    ivis_current_time() - plugin->start_time; // FIXME: real time

  /* save our GL context and send the vis a render message */
  CGLContextObj currentContext = CGLGetCurrentContext();
  if ( plugin->gl_context )
    aglSetCurrentContext( (AGLContext)(plugin->gl_context ) );

  /* call the plugin's render method */
  if ( idle )
  {
    /* idle message */
    if ( plugin->wants_idle )
      plugin->imports.visual_handler( kVisualPluginIdleMessage,
                                      &( plugin->visual_message ),
                                      plugin->vis_ref );
  }
  else
  {
    /* render message */
    plugin->imports.visual_handler( kVisualPluginRenderMessage,
                                    &( plugin->visual_message ),
                                    plugin->vis_ref );

    /* set position message */
    plugin->visual_message.u.setPositionMessage.positionTimeInMS
      = plugin->visual_message.u.renderMessage.currentPositionInMS;
    plugin->imports.visual_handler( kVisualPluginSetPositionMessage, &( plugin->visual_message ),
                                    plugin->vis_ref );
  }
  /* update message */
  plugin->imports.visual_handler( kVisualPluginUpdateMessage, NULL,
                                  plugin->vis_ref );

  /* read pixels and restore our GL context */
  CGLLockContext( CGLGetCurrentContext() );

  switch ( get_pixels( buffer, buffer_size, CGLGetCurrentContext() != currentContext ) )
  {
  case 3:
    format = ITunesPixelFormatRGB24;
    break;

  case 4:
    format = ITunesPixelFormatRGBA32;
    break;

  default:
    break;
  }

  CGLUnlockContext ( CGLGetCurrentContext() );

  /* restore our GL context */
  CGLSetCurrentContext( currentContext );
  return format;
}
Beispiel #4
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);

}