Ejemplo n.º 1
0
void AccelerateFFT<float>::setAudioFrameSize (int frameSize)
{    
    fftSize = frameSize;
    fftSizeOver2 = fftSize / 2;
    log2n = log2f (fftSize);

    if (configured)
    {
        free (complexSplit.realp);
        free (complexSplit.imagp);
        vDSP_destroy_fftsetup (fftSetupFloat);
    }
    
    complexSplit.realp = (float*)malloc (fftSize * sizeof (float));
    complexSplit.imagp = (float*)malloc (fftSize * sizeof (float));
        
    fftSetupFloat = vDSP_create_fftsetup (log2n, FFT_RADIX2);
    
    if (fftSetupFloat == nullptr)
    {
        // couldn't set up FFT
        assert (false);
    }
    
    configured = true;
}
Ejemplo n.º 2
0
FFT* newFFT(int size)
{
    FFT* fft = (FFT*)malloc(sizeof(FFT));
    if (fft == NULL)
        return NULL;
    
    // Check if the size is a power of two
    assert(POWER_OF_TWO(size));
    fft->size = size;
    fft->sizeOverTwo = fft->size / 2;
    fft->normalize = 1.0 / (2.0 * fft->size);
    
    // create fft setup
    fft->logTwo = log2f(fft->size);
    fft->fftSetup = vDSP_create_fftsetup(fft->logTwo, FFT_RADIX2);
    
    if (fft->fftSetup == 0)
    {
        freeFFT(fft);
        return NULL;
    }

    fft->window = NULL;
    
    return fft;
}
Ejemplo n.º 3
0
PitchDetector::PitchDetector(unsigned int numberOfSamples, double sampleRate)
{
    assert(numberOfSamples > 0);
    assert(sampleRate > 0);
    this->numberOfSamples = numberOfSamples;
    this->sampleRate = sampleRate;
    this->queueSize = DEFAULT_QUEUE_SIZE;
//    this->FFTBuffer = new float(numberOfSamples);
    
    this->FFTBuffer = (float *)calloc(sizeof(float), numberOfSamples);
    
    // 1.窗函数
    this->windowFunc = (float *)calloc(sizeof(float), numberOfSamples);
    vDSP_hamm_window(windowFunc, numberOfSamples, 0);

    // 2.fft处理buffer
    this->A.realp = (float  * __nonnull)malloc(sizeof(float)*(numberOfSamples/2));
    this->A.imagp = (float  * __nonnull)malloc(sizeof(float)*(numberOfSamples/2));

    // 3.能量
    this->magnitudes = (float *)malloc(sizeof(float)*(numberOfSamples/2));
    
    // 4.fft变换的预设
    float originalRealInLog2 = log2f(numberOfSamples);
    this->setupReal = vDSP_create_fftsetup(originalRealInLog2, FFT_RADIX2);

}
Ejemplo n.º 4
0
void scfft_global_init(){
	unsigned short wintype, i;
	for (wintype=0; wintype<2; ++wintype) {
		for (i=0; i< SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1; ++i) {
			fftWindow[wintype][i] = 0;
		}
		for (i= SC_FFT_LOG2_MINSIZE; i < SC_FFT_LOG2_MAXSIZE+1; ++i) {
			fftWindow[wintype][i] = scfft_create_fftwindow(wintype, i);
		}
	}
	#if SC_FFT_VDSP
		// vDSP inits its twiddle factors
		for (i= SC_FFT_LOG2_MINSIZE; i < SC_FFT_LOG2_MAXSIZE+1; ++i) {
			fftSetup[i] = vDSP_create_fftsetup (i, FFT_RADIX2);
			if(fftSetup[i] == NULL){
				printf("FFT ERROR: Mac vDSP library could not allocate FFT setup for size %i\n", 1<<i);
			}
		}
		// vDSP prepares its memory-aligned buffer for rearranging input data.
		// Note max size here - meaning max input buffer size is these two sizes added together.
		// vec_malloc used in API docs, but apparently that's deprecated and malloc is sufficient for aligned memory on OSX.
		splitBuf.realp = (float*) malloc ( SC_FFT_MAXSIZE * sizeof(float) / 2);
		splitBuf.imagp = (float*) malloc ( SC_FFT_MAXSIZE * sizeof(float) / 2);
		//printf("SC FFT global init: vDSP initialised.\n");
	#elif SC_FFT_FFTW
		//printf("SC FFT global init: FFTW, no init needed.\n");
	#endif
}
Ejemplo n.º 5
0
void ofxFFT::setup(int numFrames) {
    
    this->numFrames = numFrames;
  
    log2n = log2(numFrames);
    mFFTLength = numFrames / 2;
    
    mSpectrumAnalysis = vDSP_create_fftsetup(log2n, FFT_RADIX2);
    if (mSpectrumAnalysis == NULL) {
        printf("\nFFT_Setup failed to allocate enough memory  for"
               "the real FFT.\n");
        //std::exit(0);
    }
    
    mDspSplitComplex.realp = new float[mFFTLength];
    mDspSplitComplex.imagp = new float[mFFTLength];
    input = new float[numFrames];
    amplitude = new float[mFFTLength];
    power = new float[mFFTLength];
    
    
    mFFTNormFactor = 1.0/(2.0*numFrames);
    counter = 0;
    bReady = false;
}
Ejemplo n.º 6
0
// check the global list of windows incs ours; create if not.
// Note that expanding the table, if triggered, will cause a CPU hit as things are malloc'ed, realloc'ed, etc.
void scfft_ensurewindow(unsigned short log2_fullsize, unsigned short log2_winsize, short wintype)
{
	// Ensure we have enough space to do our calcs
	if(log2_fullsize > largest_log2n){
		largest_log2n = log2_fullsize;
 		#if SC_FFT_VDSP
			size_t newsize = (1 << largest_log2n) * sizeof(float) / 2;
			splitBuf.realp = (float*) realloc (splitBuf.realp, newsize);
			splitBuf.imagp = (float*) realloc (splitBuf.imagp, newsize);
   		#endif
	}

	// Ensure our window has been created
	if((wintype != -1) && (fftWindow[wintype][log2_winsize] == 0)){
		fftWindow[wintype][log2_winsize] = scfft_create_fftwindow(wintype, log2_winsize);
	}

	// Ensure our FFT twiddle factors (or whatever) have been created
 	#if SC_FFT_VDSP
		if(fftSetup[log2_fullsize] == 0)
			fftSetup[log2_fullsize] = vDSP_create_fftsetup (log2_fullsize, FFT_RADIX2);
	#elif SC_FFT_GREEN
		if(cosTable[log2_fullsize] == 0)
			cosTable[log2_fullsize] = create_cosTable(log2_fullsize);
   	#endif
}
Ejemplo n.º 7
0
DspRfft::DspRfft(PdMessage *initMessage, PdGraph *graph) : DspObject(0, 1, 0, 2, graph) {
  #if __APPLE__
  log2n = lrintf(log2f(blockSizeFloat));
  fftSetup = vDSP_create_fftsetup(log2n, kFFTRadix2);
  #else
  graph->printErr("[rfft~] is not supported on this platform. It is only supported on Apple OS X and iOS platforms.");
  #endif // __APPLE__
}
Ejemplo n.º 8
0
FFT::FFT (int fftSizeLog2)
    : properties (fftSizeLog2)
{
	config = vDSP_create_fftsetup (properties.fftSizeLog2, 0);

	buffer.malloc (properties.fftSize);
	bufferSplit.realp = buffer.getData();
	bufferSplit.imagp = bufferSplit.realp + properties.fftSizeHalved;
}
Ejemplo n.º 9
0
void CFFTOSX::Init(tuint uiOrder)
{
	muiOrder = uiOrder;
	muiFFTSize = Float2Int(pow(2, muiOrder));

	mA.realp = new float[muiFFTSize / 2];
	mA.imagp = new float[muiFFTSize / 2];

	mFFT = vDSP_create_fftsetup(muiOrder, FFT_RADIX2);
}
Ejemplo n.º 10
0
FFTHelper::FFTHelper ( UInt32 inMaxFramesPerSlice )
: mSpectrumAnalysis(NULL),
mFFTNormFactor(1.0/(2*inMaxFramesPerSlice)),
mFFTLength(inMaxFramesPerSlice/2),
mLog2N(Log2Ceil(inMaxFramesPerSlice))
{
    mDspSplitComplex.realp = (Float32*) calloc(mFFTLength,sizeof(Float32));
    mDspSplitComplex.imagp = (Float32*) calloc(mFFTLength, sizeof(Float32));
    mSpectrumAnalysis = vDSP_create_fftsetup(mLog2N, kFFTRadix2);
}
Ejemplo n.º 11
0
DspRfft::DspRfft(PdMessage *initMessage, PdGraph *graph) : DspObject(0, 1, 0, 2, graph) {
  #if __APPLE__
  log2n = lrintf(log2f((float) blockSizeInt));
  fftSetup = vDSP_create_fftsetup(log2n, kFFTRadix2);
  zeroBuffer = graph->getBufferPool()->getZeroBuffer(); // cache the local zero buffer
  #else
  graph->printErr("[rfft~] is not supported on this platform. It is only supported on Apple OS X and iOS platforms.");
  #endif // __APPLE__
  
  processFunction = &processSignal;
}
Ejemplo n.º 12
0
//Constructor
FFTAccelerate::FFTAccelerate (int numSamples)
{
	vDSP_Length log2n = log2f(numSamples);
	fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
	int nOver2 = numSamples/2;
	A.realp = (float *) malloc(nOver2*sizeof(float));
	A.imagp = (float *) malloc(nOver2*sizeof(float));
    window = (float *) malloc(numSamples * sizeof(float));
    in_real = (float *) malloc(numSamples * sizeof(float));
    memset(window, 0, numSamples * sizeof(float));
    vDSP_hann_window(window, numSamples, vDSP_HANN_NORM);
}
FftProcessorImplAccelerate::FftProcessorImplAccelerate( uint16_t aBandCount )
	: FftProcessorImpl( aBandCount )
{
	if( mBandCount & ( mBandCount - 1 ) ) {
		//TODO: not power of 2
	}
	
	mLog2Size = log( mBandCount * 2 ) / log( 2 );
	mFftSetup = vDSP_create_fftsetup( mLog2Size, FFT_RADIX2 );  //n = 512, log2n = 9
	
	mFftComplexBuffer.realp = (float *)malloc( mBandCount * sizeof( float ) );
	mFftComplexBuffer.imagp = (float *)malloc( mBandCount * sizeof( float ) );
}
Ejemplo n.º 14
0
FFTSetup FFTFrame::fftSetupForSize(unsigned fftSize) {
  if (!fftSetups) {
    fftSetups = (FFTSetup*)malloc(sizeof(FFTSetup) * kMaxFFTPow2Size);
    memset(fftSetups, 0, sizeof(FFTSetup) * kMaxFFTPow2Size);
  }

  int pow2size = static_cast<int>(log2(fftSize));
  ASSERT(pow2size < kMaxFFTPow2Size);
  if (!fftSetups[pow2size])
    fftSetups[pow2size] = vDSP_create_fftsetup(pow2size, FFT_RADIX2);

  return fftSetups[pow2size];
}
Ejemplo n.º 15
0
void FFT::setFFTSizeLog2 (int newFFTSizeLog2)
{
	if (newFFTSizeLog2 != properties.fftSizeLog2)
    {
		vDSP_destroy_fftsetup (config);
		
		properties = Properties (newFFTSizeLog2);
		buffer.malloc (properties.fftSize);
		bufferSplit.realp = buffer.getData();
		bufferSplit.imagp = bufferSplit.realp + properties.fftSizeHalved;
		
		config = vDSP_create_fftsetup (properties.fftSizeLog2, 0);
	}
}
Ejemplo n.º 16
0
dm_fftSetup dm_fftSetupCreate(unsigned long size_, dm_fftDirection direction_) {
  fftsetup_internal* toReturn = new fftsetup_internal();
  toReturn->direction = direction_;
#ifdef DSP_USE_ACCELERATE
  toReturn->logFftSize = log2f(size_);
  toReturn->fftSetup = vDSP_create_fftsetup(toReturn->logFftSize, FFT_RADIX2);
#else
  toReturn->fftSize = size_;
  toReturn->fftSetup = kiss_fftr_alloc(size_, (toReturn->direction == DM_FFT_FORWARD) ? 0 : 1, 0, 0);
  toReturn->temp = new float[size_];
  memset(toReturn->temp, 0, sizeof(float) * size_);
#endif
  return toReturn;
}
Ejemplo n.º 17
0
//  create a vDSP power spectrum structure 
CMFFT *FFTSpectrum( int log2n, Boolean useWindow )
{
	CMFFT *fft ;
	
	fft = ( CMFFT*)malloc( sizeof( CMFFT ) ) ;
	
	fft->style = PowerSpectrum ;
	fft->log2n = log2n ;
	fft->size = 1 << log2n ;
	fft->window = ( useWindow ) ? CMMakeModifiedBlackmanWindow( fft->size/2 ) : nil ;
	fft->z.realp = ( float* )malloc( fft->size*sizeof( float )/2 ) ;
	fft->z.imagp = ( float* )malloc( fft->size*sizeof( float )/2 ) ;
	fft->tempBuf.realp = ( float* )malloc( sizeof( float )*16384 ) ;
	fft->tempBuf.imagp = ( float* )malloc( sizeof( float )*16384 ) ;
	fft->vfft = vDSP_create_fftsetup( log2n, FFT_RADIX2 ) ;
	return fft ;
}
Ejemplo n.º 18
0
FFTBufferManager::FFTBufferManager(UInt32 inNumberFrames) :
mNeedsAudioData(0),
mHasAudioData(0),
mFFTNormFactor(1.0/(2*inNumberFrames)),
mAdjust0DB(1.5849e-13),
m24BitFracScale(16777216.0f),
mFFTLength(inNumberFrames/2),
mLog2N(Log2Ceil(inNumberFrames)),
mNumberFrames(inNumberFrames),
mAudioBufferSize(inNumberFrames * sizeof(Float32)),
mAudioBufferCurrentIndex(0)

{
    mAudioBuffer = (Float32*) calloc(mNumberFrames,sizeof(Float32));
    mDspSplitComplex.realp = (Float32*) calloc(mFFTLength,sizeof(Float32));
    mDspSplitComplex.imagp = (Float32*) calloc(mFFTLength, sizeof(Float32));
    mSpectrumAnalysis = vDSP_create_fftsetup(mLog2N, kFFTRadix2);
	OSAtomicIncrement32Barrier(&mNeedsAudioData);
}
Ejemplo n.º 19
0
void ofxAudioUnitFftNode::setFftBufferSize(unsigned int bufferSize)
{
	_log2N = (unsigned int) ceilf(log2f(bufferSize));
	_N = 1 << _log2N;
	
	// if the new buffer size is bigger than what we've allocated for,
	// free everything and allocate anew (otherwise re-use)
	if(_log2N > _currentMaxLog2N) {
		freeBuffers();
		_fftData.realp = (float *)calloc(_N / 2, sizeof(float));
		_fftData.imagp = (float *)calloc(_N / 2, sizeof(float));
		_window = (float *)calloc(_N, sizeof(float));
		_fftSetup = vDSP_create_fftsetup(_log2N, kFFTRadix2);
		_currentMaxLog2N = _log2N;
	}

	generateWindow(_outputSettings.window, _window, _N);
	setBufferSize(_N);
}
Ejemplo n.º 20
0
CMFFT *FFTForward( int log2n, Boolean useWindow )
{
	CMFFT *fft ;
	
	fft = ( CMFFT*)malloc( sizeof( CMFFT ) ) ;
	
	fft->style = Forward ;
	fft->log2n = log2n ;
	fft->size = 1 << log2n ;
	fft->window = ( useWindow ) ? CMMakeModifiedBlackmanWindow( fft->size ) : nil ;
	fft->tempBuf.realp = (float*)malloc( sizeof(float)*16384 ) ;
	fft->tempBuf.imagp = (float*)malloc( sizeof(float)*16384 ) ;
	if ( useWindow ) {
		fft->realBuf = (float*)malloc( sizeof(float)*fft->size ) ;
		fft->imagBuf = (float*)malloc( sizeof(float)*fft->size ) ;
	}
	fft->vfft = vDSP_create_fftsetup( log2n, FFT_RADIX2 ) ;
	return fft ;
}
Ejemplo n.º 21
0
// Demonstrate vDSP FFT functions.
void DemonstrateFFT(void)
{
	printf("Begin %s.\n", __func__);

	// Initialize data for the FFT routines.
	FFTSetup Setup = vDSP_create_fftsetup(Log2N, FFT_RADIX2);
	if (Setup == NULL)
	{
		fprintf(stderr, "Error, vDSP_create_fftsetup failed.\n");
		exit (EXIT_FAILURE);
	}

	DemonstratevDSP_fft_zrip(Setup);
	DemonstratevDSP_fft_zrop(Setup);
	DemonstratevDSP_fft_zip(Setup);
	DemonstratevDSP_fft_zop(Setup);

	vDSP_destroy_fftsetup(Setup);

	printf("\nEnd %s.\n\n\n", __func__);
}
Ejemplo n.º 22
0
/* constructor */
fft::fft(int fftSize) {
	n = fftSize;
	half = fftSize / 2;
	//use malloc for 16 byte alignment
	in_real = (float *) malloc(n * sizeof(float));
	in_img = (float *) malloc(n * sizeof(float));
	out_real = (float *) malloc(n * sizeof(float));
	out_img = (float *) malloc(n * sizeof(float));

#ifdef __APPLE_CC__
	log2n = log2(n);
	A.realp = (float *) malloc(half * sizeof(float));
    A.imagp = (float *) malloc(half * sizeof(float));
	setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);
    if (setupReal == NULL) {
        printf("\nFFT_Setup failed to allocate enough memory  for"
               "the real FFT.\n");
    }
	polar = (float *) malloc(n * sizeof(float));
#endif
}
Ejemplo n.º 23
0
FFT32 *FFT32_new(size_t FFTFrameSize, FFTWindowType windowType)
{
    FFT32 *self = calloc(1, sizeof(FFT32));
    
    if (FFTFrameSize < FFT_minimumFFTFrameSize) {
        
        printf("FFTFrameSize specified is lower than minimum, defaulting to minimum\n");
        FFTFrameSize = FFT_minimumFFTFrameSize;
    }
    
    self->FFTFrameSize = nextPowerOfTwo(FFTFrameSize);
    self->FFTFrameSizeOver2 = self->FFTFrameSize / 2;
    self->log2n = log2f((Float32)FFTFrameSize);
    self->frameBuffer = calloc(self->FFTFrameSize, sizeof(Float32));
    self->window = calloc(self->FFTFrameSize, sizeof(Float32));
    self->interlacedPolar = calloc(self->FFTFrameSize, sizeof(Float32));
    self->splitComplex.realp = calloc(self->FFTFrameSizeOver2, sizeof(Float32));
    self->splitComplex.imagp = calloc(self->FFTFrameSizeOver2, sizeof(Float32));
    self->FFTData = vDSP_create_fftsetup(self->log2n, FFT_RADIX2);
    
    FFT32_configureWindow(self, windowType);
    
    return self;
}
Ejemplo n.º 24
0
int main(int argc, char *argv[])
{
    // Initialize the pseudo-random number generator.
    InitializeRandom();

    // Initialize FFT data.
    FFTSetup Setup = vDSP_create_fftsetup(Log2SampleLength, FFT_RADIX2);
    if (Setup == 0)
    {
        fprintf(stderr, "Error, unable to create FFT setup.\n");
        exit(EXIT_FAILURE);
    }

    /*	If there are no command-line arguments, prompt for keys
    	interactively.
    */
    if (argc <= 1)
    {
        // Process keys for the user until they are done.
        int c;
        while (1)
        {
            // Prompt the user.
            printf(
                "Please enter a key (one of 0-9, *, #, or A-D):  ");

            // Skip whitespace except newlines.
            do
                c = getchar();
            while (c != '\n' && isspace(c));

            // When there is a blank line or an EOF, quit.
            if (c == '\n' || c == EOF)
                break;

            // Look up the key in the table.
            FrequencyPair F = ConvertKeyToFrequencies(toupper(c));

            // If it is a valid key, demonstrate the FFT.
            if (F.Frequency[0] != 0)
                Demonstrate(Setup, F);

            // Skip anything else on the line.
            do
                c = getchar();
            while (c != EOF && c != '\n');

            // When the input ends, quit.  Otherwise, do more.
            if (c == EOF)
                break;
        }

        // Do not leave the cursor in the middle of a line.
        if (c != '\n')
            printf("\n");
    }

    // If there is one command line argument, process the keys in it.
    else if (argc == 2)
    {
        for (char *p = argv[1]; *p; ++p)
        {
            // Look up the key in the table.
            FrequencyPair F = ConvertKeyToFrequencies(toupper(*p));

            // If it is a valid key, demonstrate the FFT.
            if (F.Frequency[0] != 0)
            {
                printf("Simulating key %c.\n", *p);
                Demonstrate(Setup, F);
            }
            else
                fprintf(stderr,
                        "Error, key %c not recognized.\n", *p);
        }
    }

    // If there are too many arguments, print a usage message.
    else
    {
        fprintf(stderr,
                "Usage:  %s [telephone keys 0-9, #, *, or A-D]\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    // Release resources.
    vDSP_destroy_fftsetup(Setup);

    return 0;
}
Ejemplo n.º 25
0
void benchmark_ffts(int N, int cplx) {
  int Nfloat = (cplx ? N*2 : N);
  int Nbytes = Nfloat * sizeof(float);
  float *X = pffft_aligned_malloc(Nbytes), *Y = pffft_aligned_malloc(Nbytes), *Z = pffft_aligned_malloc(Nbytes);

  double t0, t1, flops;

  int k;
  int max_iter = 5120000/N*4;
#ifdef __arm__
  max_iter /= 4;
#endif
  int iter;

  for (k = 0; k < Nfloat; ++k) {
    X[k] = 0; //sqrtf(k+1);
  }

  // FFTPack benchmark
  {
    float *wrk = malloc(2*Nbytes + 15*sizeof(float));
    int max_iter_ = max_iter/pffft_simd_size(); if (max_iter_ == 0) max_iter_ = 1;
    if (cplx) cffti(N, wrk);
    else      rffti(N, wrk);
    t0 = uclock_sec();  
    
    for (iter = 0; iter < max_iter_; ++iter) {
      if (cplx) {
        cfftf(N, X, wrk);
        cfftb(N, X, wrk);
      } else {
        rfftf(N, X, wrk);
        rfftb(N, X, wrk);
      }
    }
    t1 = uclock_sec();
    free(wrk);
    
    flops = (max_iter_*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); // see http://www.fftw.org/speed/method.html
    show_output("FFTPack", N, cplx, flops, t0, t1, max_iter_);
  }

#ifdef HAVE_VECLIB
  int log2N = (int)(log(N)/log(2) + 0.5f);
  if (N == (1<<log2N)) {
    FFTSetup setup;

    setup = vDSP_create_fftsetup(log2N, FFT_RADIX2);
    DSPSplitComplex zsamples;
    zsamples.realp = &X[0];
    zsamples.imagp = &X[Nfloat/2];
    t0 = uclock_sec();  
    for (iter = 0; iter < max_iter; ++iter) {
      if (cplx) {
        vDSP_fft_zip(setup, &zsamples, 1, log2N, kFFTDirection_Forward);
        vDSP_fft_zip(setup, &zsamples, 1, log2N, kFFTDirection_Inverse);
      } else {
        vDSP_fft_zrip(setup, &zsamples, 1, log2N, kFFTDirection_Forward); 
        vDSP_fft_zrip(setup, &zsamples, 1, log2N, kFFTDirection_Inverse);
      }
    }
    t1 = uclock_sec();
    vDSP_destroy_fftsetup(setup);

    flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); // see http://www.fftw.org/speed/method.html
    show_output("vDSP", N, cplx, flops, t0, t1, max_iter);
  } else {
    show_output("vDSP", N, cplx, -1, -1, -1, -1);
  }
#endif
  
#ifdef HAVE_FFTW
  {
    fftwf_plan planf, planb;
    fftw_complex *in = (fftw_complex*) fftwf_malloc(sizeof(fftw_complex) * N);
    fftw_complex *out = (fftw_complex*) fftwf_malloc(sizeof(fftw_complex) * N);
    memset(in, 0, sizeof(fftw_complex) * N);
    int flags = (N < 40000 ? FFTW_MEASURE : FFTW_ESTIMATE);  // measure takes a lot of time on largest ffts
    //int flags = FFTW_ESTIMATE;
    if (cplx) {
      planf = fftwf_plan_dft_1d(N, (fftwf_complex*)in, (fftwf_complex*)out, FFTW_FORWARD, flags);
      planb = fftwf_plan_dft_1d(N, (fftwf_complex*)in, (fftwf_complex*)out, FFTW_BACKWARD, flags);
    } else {
      planf = fftwf_plan_dft_r2c_1d(N, (float*)in, (fftwf_complex*)out, flags);
      planb = fftwf_plan_dft_c2r_1d(N, (fftwf_complex*)in, (float*)out, flags);
    }

    t0 = uclock_sec();  
    for (iter = 0; iter < max_iter; ++iter) {
      fftwf_execute(planf);
      fftwf_execute(planb);
    }
    t1 = uclock_sec();

    fftwf_destroy_plan(planf);
    fftwf_destroy_plan(planb);
    fftwf_free(in); fftwf_free(out);

    flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); // see http://www.fftw.org/speed/method.html
    show_output((flags == FFTW_MEASURE ? "FFTW (meas.)" : " FFTW (estim)"), N, cplx, flops, t0, t1, max_iter);
  }
#endif  

  // PFFFT benchmark
  {
    PFFFT_Setup *s = pffft_new_setup(N, cplx ? PFFFT_COMPLEX : PFFFT_REAL);
    if (s) {
      t0 = uclock_sec();  
      for (iter = 0; iter < max_iter; ++iter) {
        pffft_transform(s, X, Z, Y, PFFFT_FORWARD);
        pffft_transform(s, X, Z, Y, PFFFT_BACKWARD);
      }
      t1 = uclock_sec();
      pffft_destroy_setup(s);
    
      flops = (max_iter*2) * ((cplx ? 5 : 2.5)*N*log((double)N)/M_LN2); // see http://www.fftw.org/speed/method.html
      show_output("PFFFT", N, cplx, flops, t0, t1, max_iter);
    }
  }

  if (!array_output_format) {
    printf("--\n");
  }

  pffft_aligned_free(X);
  pffft_aligned_free(Y);
  pffft_aligned_free(Z);
}
Ejemplo n.º 26
0
void computeReferenceF(clFFT_SplitComplex *out, clFFT_Dim3 n, 
					  unsigned int batchSize, clFFT_Dimension dim, clFFT_Direction dir)
{
	FFTSetup plan_vdsp;
	DSPSplitComplex out_vdsp;
	FFTDirection dir_vdsp = dir == clFFT_Forward ? FFT_FORWARD : FFT_INVERSE;
	
	unsigned int i, j, k;
	unsigned int stride;
	unsigned int log2Nx = (unsigned int) log2(n.x);
	unsigned int log2Ny = (unsigned int) log2(n.y);
	unsigned int log2Nz = (unsigned int) log2(n.z);
	unsigned int log2N;
	
	log2N = log2Nx;
	log2N = log2N > log2Ny ? log2N : log2Ny;
	log2N = log2N > log2Nz ? log2N : log2Nz;
	
	plan_vdsp = vDSP_create_fftsetup(log2N, 2);
	
	switch(dim)
	{
		case clFFT_1D:
			
			for(i = 0; i < batchSize; i++)
			{
				stride = i * n.x;
				out_vdsp.realp  = out->real  + stride;
				out_vdsp.imagp  = out->imag  + stride;
				
			    vDSP_fft_zip(plan_vdsp, &out_vdsp, 1, log2Nx, dir_vdsp);
			}
			break;
			
		case clFFT_2D:
			
			for(i = 0; i < batchSize; i++)
			{
				for(j = 0; j < n.y; j++)
				{
					stride = j * n.x + i * n.x * n.y;
					out_vdsp.realp = out->real + stride;
					out_vdsp.imagp = out->imag + stride;
					
					vDSP_fft_zip(plan_vdsp, &out_vdsp, 1, log2Nx, dir_vdsp);
				}
			}
			for(i = 0; i < batchSize; i++)
			{
				for(j = 0; j < n.x; j++)
				{
					stride = j + i * n.x  * n.y;
					out_vdsp.realp = out->real + stride;
					out_vdsp.imagp = out->imag + stride;
					
					vDSP_fft_zip(plan_vdsp, &out_vdsp, n.x, log2Ny, dir_vdsp);
				}
			}
			break;
			
		case clFFT_3D:
			
			for(i = 0; i < batchSize; i++)
			{
				for(j = 0; j < n.z; j++)
				{
					for(k = 0; k < n.y; k++)
					{
						stride = k * n.x + j * n.x * n.y + i * n.x * n.y * n.z;
						out_vdsp.realp = out->real + stride;
						out_vdsp.imagp = out->imag + stride;
						
						vDSP_fft_zip(plan_vdsp, &out_vdsp, 1, log2Nx, dir_vdsp);
					}
				}
			}
			for(i = 0; i < batchSize; i++)
			{
				for(j = 0; j < n.z; j++)
				{
					for(k = 0; k < n.x; k++)
					{
						stride = k + j * n.x * n.y + i * n.x * n.y * n.z;
						out_vdsp.realp = out->real + stride;
						out_vdsp.imagp = out->imag + stride;
						
						vDSP_fft_zip(plan_vdsp, &out_vdsp, n.x, log2Ny, dir_vdsp);
					}
				}
			}
			for(i = 0; i < batchSize; i++)
			{
				for(j = 0; j < n.y; j++)
				{
					for(k = 0; k < n.x; k++)
					{
						stride = k + j * n.x + i * n.x * n.y * n.z;
						out_vdsp.realp = out->real + stride;
						out_vdsp.imagp = out->imag + stride;
						
						vDSP_fft_zip(plan_vdsp, &out_vdsp, n.x*n.y, log2Nz, dir_vdsp);
					}
				}
			}
			break;
	}
	
	vDSP_destroy_fftsetup(plan_vdsp);
}
Ejemplo n.º 27
0
//Processes a frame and returns output image
bool HiLight::processFrame(const cv::Mat& inputFrame, int* screen_position, double current_timestamp, char *results, bool* denoise_check, bool* first_bit_check, int* hilight_line_index, char* hilight_results_tmp )
{
    *denoise_check = false;
    *first_bit_check = false;
    if(!initialized){
        initialized = true;
        for(int i = 0; i<grid_x; i++){
            for(int j = 0; j<grid_y; j++ ){
                for (int k = 0; k < first_bit_window; k++){
                    first_bit_color_window[i][j][k] = 0;
                }
                for (int k = 0; k < N; k++){
                    grid_color_intensity[i][j][k] = 0;
                    hilight_results_stack[i][j][k] = 0;
                }
                hilight_results[i][j] = 0;
            }
        }
        if (isImage){
            MVDR = true;
            first_2_ratio = 0.6;//0.8
            first_bit_voting = 0.5;//0.7
        }else{
            MVDR = false;
            first_2_ratio = 0.8; //0.7
            first_bit_voting = 0.7; //0.6
        }
        window_index = 0;
        first_bit_detected = false;
        first_bit_index = 0;
        hilight_stack_index = 0;
        start_time = current_timestamp;
        current_time = current_timestamp;
        denoise_start = false;
        MVDR_index = 0;
        bit_counter = 0;
        results_stack_counter = 0;
        fftSetup = vDSP_create_fftsetup(LOG_N, kFFTRadix2);
        start_receiving = false;
        counter_after_detect_1= 0;
        
        first_bit_1_detected = false;
        first_bit_2_detected = false;
        hilight_first_bit_index = 0;
        hilight_first_bit_counter = 0;
        hilight_first_bit_position = 0;
        
        if (screen_position[2] < screen_position[4]){
            image_ROI_position[0].y = screen_position[2];
        }else{
            image_ROI_position[0].y = screen_position[4];
        }
        
        if (screen_position[1] < screen_position[7]){
            image_ROI_position[0].x = screen_position[1];
        }else{
            image_ROI_position[0].x = screen_position[7];
        }
        
        if (screen_position[6] < screen_position[8]){
            image_ROI_position[1].y = screen_position[8];
        }else{
            image_ROI_position[1].y = screen_position[6];
        }
        
        if (screen_position[5] < screen_position[3]){
            image_ROI_position[1].x = screen_position[3];
        }else{
            image_ROI_position[1].x = screen_position[5];
        }
        
        if (isImage){
            // Set grids points to calculate the grid position
            for (int i = 0; i <= grid_x * grid_x_MVDR; i++){
                grids_points_top_image[i].x = screen_position[1] + (screen_position[3] - screen_position[1]) / grid_x / grid_x_MVDR * i;
                grids_points_top_image[i].y = screen_position[2] + (screen_position[4] - screen_position[2]) / grid_x / grid_x_MVDR * i;
                grids_points_bottom_image[i].x = screen_position[7] + (screen_position[5] - screen_position[7]) / grid_x / grid_x_MVDR * i;
                grids_points_bottom_image[i].y = screen_position[8] + (screen_position[6] - screen_position[8]) / grid_x / grid_x_MVDR * i;
            }
            
            for (int i = 0; i <= grid_y * grid_y_MVDR; i++){
                grids_points_left_image[i].x = screen_position[1] + (screen_position[7] - screen_position[1]) / grid_y / grid_y_MVDR * i;
                grids_points_left_image[i].y = screen_position[2] + (screen_position[8] - screen_position[2]) / grid_y / grid_y_MVDR * i;
                grids_points_right_image[i].x = screen_position[3] + (screen_position[5] - screen_position[3]) / grid_y / grid_y_MVDR * i;
                grids_points_right_image[i].y = screen_position[4] + (screen_position[6] - screen_position[4]) / grid_y / grid_y_MVDR * i;
            }
            
            for (int i = 0; i < grid_x * grid_x_MVDR; i++){
                for (int j = 0; j < grid_y * grid_y_MVDR; j++){
                    cv::Point2f r1;
                    cv::Point2f r2;
                    cv::Point2f r3;
                    cv::Point2f r4;
                    intersection(grids_points_top_image[i], grids_points_bottom_image[i], grids_points_left_image[j], grids_points_right_image[j], r1);//top left
                    intersection(grids_points_top_image[i+1], grids_points_bottom_image[i+1], grids_points_left_image[j], grids_points_right_image[j], r2);//top right
                    intersection(grids_points_top_image[i+1], grids_points_bottom_image[i+1], grids_points_left_image[j+1], grids_points_right_image[j+1], r3);// bottom right
                    intersection(grids_points_top_image[i], grids_points_bottom_image[i], grids_points_left_image[j+1], grids_points_right_image[j+1], r4);//bottom left
                    
                    //refine grid_position
                    if (r1.x <= r4.x){
                        grids_position_image[i][j][0].x = r4.x - image_ROI_position[0].x;
                    }else{
                        grids_position_image[i][j][0].x = r1.x - image_ROI_position[0].x;
                    }
                    
                    if (r1.y <= r2.y){
                        grids_position_image[i][j][0].y = r2.y - image_ROI_position[0].y;
                    }else{
                        grids_position_image[i][j][0].y = r1.y - image_ROI_position[0].y;
                    }
                    
                    if (r3.x <= r2.x){
                        grids_position_image[i][j][1].x = r3.x - image_ROI_position[0].x;
                    }else{
                        grids_position_image[i][j][1].x = r2.x - image_ROI_position[0].x;
                    }
                    
                    if (r3.y <= r4.y){
                        grids_position_image[i][j][1].y = r3.y - image_ROI_position[0].y;
                    }else{
                        grids_position_image[i][j][1].y = r4.y - image_ROI_position[0].y;
                    }
                }
            }
        }else{
            // Set grids points to calculate the grid position
            for (int i = 0; i <= grid_x; i++){
                grids_points_top_video[i].x = screen_position[1] + (screen_position[3] - screen_position[1]) / grid_x * i;
                grids_points_top_video[i].y = screen_position[2] + (screen_position[4] - screen_position[2]) / grid_x * i;
                grids_points_bottom_video[i].x = screen_position[7] + (screen_position[5] - screen_position[7]) / grid_x * i;
                grids_points_bottom_video[i].y = screen_position[8] + (screen_position[6] - screen_position[8]) / grid_x * i;
            }
            
            for (int i = 0; i <= grid_y; i++){
                grids_points_left_video[i].x = screen_position[1] + (screen_position[7] - screen_position[1]) / grid_y * i;
                grids_points_left_video[i].y = screen_position[2] + (screen_position[8] - screen_position[2]) / grid_y * i;
                grids_points_right_video[i].x = screen_position[3] + (screen_position[5] - screen_position[3]) / grid_y * i;
                grids_points_right_video[i].y = screen_position[4] + (screen_position[6] - screen_position[4]) / grid_y * i;
            }
            
            for (int i = 0; i < grid_x; i++){
                for (int j = 0; j < grid_y; j++){
                    cv::Point2f r1;
                    cv::Point2f r2;
                    cv::Point2f r3;
                    cv::Point2f r4;
                    intersection(grids_points_top_video[i], grids_points_bottom_video[i], grids_points_left_video[j], grids_points_right_video[j], r1);//top left
                    intersection(grids_points_top_video[i+1], grids_points_bottom_video[i+1], grids_points_left_video[j], grids_points_right_video[j], r2);//top right
                    intersection(grids_points_top_video[i+1], grids_points_bottom_video[i+1], grids_points_left_video[j+1], grids_points_right_video[j+1], r3);// bottom right
                    intersection(grids_points_top_video[i], grids_points_bottom_video[i], grids_points_left_video[j+1], grids_points_right_video[j+1], r4);//bottom left
                    
                    //refine grid_position
                    if (r1.x <= r4.x){
                        grids_position_video[i][j][0].x = r4.x - image_ROI_position[0].x;
                    }else{
                        grids_position_video[i][j][0].x = r1.x - image_ROI_position[0].x;
                    }
                    
                    if (r1.y <= r2.y){
                        grids_position_video[i][j][0].y = r2.y - image_ROI_position[0].y;
                    }else{
                        grids_position_video[i][j][0].y = r1.y - image_ROI_position[0].y;
                    }
                    
                    if (r3.x <= r2.x){
                        grids_position_video[i][j][1].x = r3.x - image_ROI_position[0].x;
                    }else{
                        grids_position_video[i][j][1].x = r2.x - image_ROI_position[0].x;
                    }
                    
                    if (r3.y <= r4.y){
                        grids_position_video[i][j][1].y = r3.y - image_ROI_position[0].y;
                    }else{
                        grids_position_video[i][j][1].y = r4.y - image_ROI_position[0].y;
                    }
                }
            }
        }
        
        srcTri[0] = cv::Point2f( screen_position[2],screen_position[1] );
        srcTri[1] = cv::Point2f( screen_position[4],screen_position[3] );
        srcTri[2] = cv::Point2f( screen_position[6],screen_position[5] );
        
        dist_top = sqrt(pow(screen_position[4]-screen_position[2],2.0) + pow(screen_position[3]-screen_position[1],2.0));
        dstTri[0] = cv::Point2f( screen_position[2],screen_position[1] );
        dstTri[1] = cv::Point2f( screen_position[2],screen_position[1] + dist_top );
        dstTri[2] = cv::Point2f( screen_position[2] + (int)(dist_top*transmitter_screen_ratio),screen_position[1] + dist_top);
        warp_mat = getAffineTransform( srcTri, dstTri );
    }else{
        current_time = current_timestamp;
    }
    
    //crop the transmitter screen from the captured image
    cv::Mat image_ROI = inputFrame(cv::Range(image_ROI_position[0].y, image_ROI_position[1].y), cv::Range(image_ROI_position[0].x, image_ROI_position[1].x));
    getGray_HiLight(image_ROI, grayImage);
    image_ROI.release();
    
    for (int c = 0; c < grid_x; c++){
        for (int r = 0; r < grid_y; r++){
            brightness[c][r] = 0;
        }
    }
    if (isImage){
        int brightness_c = 0;
        int brightness_r = 0;
        for (int c = 0; c < grid_x * grid_x_MVDR; c++){
            for (int r = 0; r < grid_y * grid_y_MVDR; r++)
            {
                cv::Mat tile = grayImage(cv::Range(grids_position_image[c][r][0].y + grid_margin, grids_position_image[c][r][1].y - grid_margin)
                                         , cv::Range(grids_position_image[c][r][0].x + grid_margin, grids_position_image[c][r][1].x - grid_margin));
                
                cv::Scalar pixel_scalar = cv::mean(tile);
                tile.release();
                float brightness_tmp =pixel_scalar[0];
                
                if (MVDR){
                    if(!denoise_start && MVDR_index < MVDR_frame){
                        grid_color_intensity_MVDR[c][r][MVDR_index] = brightness_tmp;
                        if ( c == grid_x * grid_x_MVDR -1 && r == grid_y * grid_y_MVDR - 1){
                            MVDR_index++;
                        }
                    }else if(!denoise_start && MVDR_index >= MVDR_frame){
                        denoise_start = true;
                        *denoise_check = true;
                        get_MVDR_weighting(grid_color_intensity_MVDR, MVDR_weighting);
                        
                        //print MVDR matrix
                        if (isDebug){
                            for (int i = 0; i < grid_x * grid_x_MVDR; i++){
                                for (int j = 0; j < grid_y * grid_y_MVDR; j++){
                                    printf("%f\t", MVDR_weighting[i][j]);
                                }
                                printf("\n");
                            }
                        }
                    }else{
                        brightness_c = floor(c*1.0/grid_x_MVDR);
                        brightness_r = floor(r*1.0/grid_y_MVDR);
                        brightness[brightness_c][brightness_r] = brightness[brightness_c][brightness_r] + brightness_tmp * MVDR_weighting[c][r];
                    }
                }else{
                    brightness_c = floor(c*1.0/grid_x_MVDR);
                    brightness_r = floor(r*1.0/grid_y_MVDR);
                    brightness[brightness_c][brightness_r] = brightness[brightness_c][brightness_r] + brightness_tmp;
                }
            }
        }
    }else{
        for (int c = 0; c < grid_x; c++){
            for (int r = 0; r < grid_y; r++)
            {
                cv::Mat tile = grayImage(cv::Range(grids_position_video[c][r][0].y + grid_margin, grids_position_video[c][r][1].y - grid_margin)
                                         , cv::Range(grids_position_video[c][r][0].x + grid_margin, grids_position_video[c][r][1].x - grid_margin));
                
                cv::Scalar pixel_scalar = cv::mean(tile);
                tile.release();
                float brightness_tmp =pixel_scalar[0];
                brightness[c][r] = brightness_tmp;
            }
        }
    }

    if (denoise_start || !MVDR){
        for (int c = 0; c < grid_x; c++){
            for (int r = 0; r < grid_y; r++){
                if (window_index<(N-1)) {
                    grid_color_intensity[c][r][window_index] = brightness[c][r];
                    window_index++;
                }else{
                    int i;
                    float fft_sum_N_over_2 = 0;
                    for (i = 1; i < N; i++){
                        grid_color_intensity[c][r][i-1] = grid_color_intensity[c][r][i];
                    }
                    grid_color_intensity[c][r][N-1] = brightness[c][r];
                    
                    for (i = 0; i < N/2; i++){
                        fft_sum_N_over_2 = fft_sum_N_over_2 + grid_color_intensity[c][r][2*i] - grid_color_intensity[c][r][2*i+1];
                    }

                    // Initialize the input buffer with a sinusoid
                    
                    // We need complex buffers in two different formats!
                    tempSplitComplex.realp = new float[N/2];
                    tempSplitComplex.imagp = new float[N/2];
                    
                    // ----------------------------------------------------------------
                    // Forward FFT
                    
                    // Scramble-pack the real data into complex buffer in just the way that's
                    // required by the real-to-complex FFT function that follows.
                    vDSP_ctoz((DSPComplex*)grid_color_intensity[c][r], 2, &tempSplitComplex, 1, N/2);
                    
                    // Do real->complex forward FFT
                    vDSP_fft_zrip(fftSetup, &tempSplitComplex, 1, LOG_N, kFFTDirection_Forward);
                    
                    int max_pulse_index = object_pulse_threashold;
                    float max_pulse = -100;
                    float object_pulse_power_1 = LinearToDecibel(pow (fft_sum_N_over_2, 2.0)/ N);
                    float object_pulse_power_2;
                    int object_pulse_force;
                    int object_pulse;
                    for (int k = object_pulse_threashold; k < N/2; k++)
                    {
                        float spectrum = LinearToDecibel((pow (tempSplitComplex.realp[k], 2.0) + pow (tempSplitComplex.imagp[k], 2.0))/ 4/ N);
                        if (max_pulse<spectrum){
                            max_pulse = spectrum;
                            max_pulse_index = k;
                        }
                        if(k == object_pulse_2){
                            object_pulse_power_2 = spectrum;
                        }
                    }
                    
                    delete tempSplitComplex.realp;
                    delete tempSplitComplex.imagp;
                    
                    if(max_pulse < object_pulse_power_1 && object_pulse_power_1 > -25){
                        object_pulse = 1;
                    }else if(max_pulse == object_pulse_power_2){
                        object_pulse = 2;
                    }else{
                        object_pulse = 0;
                    }
                    
                    if(object_pulse_power_1 >= object_pulse_power_2){
                        object_pulse_force = 1;
                    }else{
                        object_pulse_force = 2;
                    }
                    
                    //decode data by find the peak frequency power
                    if (first_bit_detected){
                        if (first_bit_1_detected && isCalibrate){
                            hilight_first_bit_stack[c][r][hilight_first_bit_index] = object_pulse_force;
                        }
                        if(current_time - start_time >= N / 60.0 * (bit_counter + 1)){
                            hilight_results[c][r] = get_hilight_results(hilight_results_stack[c][r], hilight_stack_index);
                            hilight_results_stack[c][r][0] = object_pulse_force;
                        }else{
                            hilight_results_stack[c][r][hilight_stack_index] = object_pulse_force;
                        }
                    }else{
                        first_bit_color_window[c][r][first_bit_index] = object_pulse;
                    }
                }
            }
        }

        if (first_bit_1_detected && isCalibrate){
            hilight_first_bit_timestamp[hilight_first_bit_index++] = current_time;
        }if(first_bit_2_detected && isCalibrate){
            first_bit_2_detected = false;
            hilight_first_bit_counter++;
            if (hilight_first_bit_counter == N/2){
                calibrate_first_bit_position();
            }
        }
        if (first_bit_detected){
            if(current_time - start_time >= N / 60.0 * (bit_counter + 1)){
                int counter_for_2 = 0;
                for (int i = 0; i < grid_x; i++){
                    for (int j = 0; j <  grid_y; j++){
                        if (isDebug || start_receiving){
                            printf("%d ",hilight_results[i][j]);
                        }
                        if (hilight_results[i][j] == 2){
                            counter_for_2++;
                        }
                    }
                }
                if (isDebug || start_receiving){
                    printf("\n");
                }
                hilight_stack_index = 1;
                bit_counter++;
                
                if (!start_receiving){
                    counter_after_detect_1++;
                    if (counter_after_detect_1 > 3){
                        reset();
                    }else{
                        if(counter_for_2 >= (double)grid_x * grid_y * first_2_ratio){
                            first_bit_2_detected = true;
                            start_receiving = true;
                            *first_bit_check = true;
                            if (isDebug){
                                printf("\n");
                            }
                        }
                    }
                    return false;
                }else{
                    int results_counter_tmp =0;
                    for (int i = 0; i < grid_x; i++){
                        for (int j = 0; j <  grid_y; j++){
                            output_bit_stack[results_stack_counter++] = hilight_results[i][j];
                            hilight_results_tmp[results_counter_tmp++] = hilight_results[i][j] + '0' - 1;
                        }
                    }
                    hilight_line_index[0] = results_stack_counter/grid_x/grid_y;
                    
                    if (results_stack_counter == output_bit_stck_length){
                        results_stack_counter = 0;
                        get_char_from_bits(output_bit_stack, results);
                        
                        printf("%s\n",results);
                        
                        if (demo){
                            debug_reset();
                            return true;
                        }else{
                            debug_reset();
                            return false;
                        }
                    }else{
                        return false;
                    }
                }
            }else{
                hilight_stack_index++;
            }
        }else{
            if(first_bit_index<first_bit_window-1){
                first_bit_index++;
            }else{
                first_bit_detected = detect_first_bit(first_bit_color_window);
                if (first_bit_detected){
                    if (isCalibrate){
                        first_bit_1_detected = true;
                    }
                    start_time = current_time;
                }
            }
        }
    }
    return false;
}