Пример #1
0
void DspRifft::processDspWithIndex(int fromIndex, int toIndex) {
  #if __APPLE__
  DSPSplitComplex inputVector;
  inputVector.realp = dspBufferAtInlet[0];
  inputVector.imagp = dspBufferAtInlet[1];
  DSPSplitComplex outputVector;
  outputVector.realp = dspBufferAtOutlet[0];
  outputVector.imagp = (float *) alloca(blockSizeInt*sizeof(float)); // this buffer will not contain any useful data
  vDSP_fft_zop(fftSetup, &inputVector, 1, &outputVector, 1, log2n, kFFTDirection_Inverse);
  #endif // __APPLE__
}
Пример #2
0
void DspRfft::processDspWithIndex(int fromIndex, int toIndex) {
  #if __APPLE__
  DSPSplitComplex inputVector;
  inputVector.realp = dspBufferAtInlet0;
  inputVector.imagp = DspObject::zeroBuffer;
  DSPSplitComplex outputVector;
  outputVector.realp = dspBufferAtOutlet0;
  outputVector.imagp = dspBufferAtOutlet[1];
  vDSP_fft_zop(fftSetup, &inputVector, 1, &outputVector, 1, log2n, kFFTDirection_Forward);
  
  // NOTE(mhroth): vDSP_fft_zop outputs the entire series of symmetric coefficients.
  // Pd only returns the unique values. The below code makes this object output values in the same
  // way that Pd does. But since the Apple fft and ifft functions require the symmetric values,
  // we leave it like this for now.
  
  //int halfBlockSize = blockSizeInt >> 1;
  //memset(dspBufferAtOutlet0+halfBlockSize+1, 0, (halfBlockSize-1) * sizeof(float));
  //memset(dspBufferAtOutlet[1]+halfBlockSize, 0, halfBlockSize * sizeof(float));
  #endif // __APPLE__
}
/*	Demonstrate the complex one-dimensional out-of-place FFT, vDSP_fft_zop.

	The out-of-place FFT writes results into a different array than the
	input.
*/
static void DemonstratevDSP_fft_zop(FFTSetup Setup)
{
	/*	Define strides for the arrays be passed to the FFT.  In many
		applications, the strides are one and are passed to the vDSP
		routine as constants.
	*/
	const vDSP_Stride SignalStride = 1, ObservedStride = 1;

	// Define a variable for a loop iterator.
	vDSP_Length i;

	// Define some variables used to time the routine.
	ClockData t0, t1;
	double Time;

	printf("\n\tOne-dimensional complex FFT of %lu elements.\n",
		(unsigned long) N);

	// Allocate memory for the arrays.
	DSPSplitComplex Signal, Observed;
	Signal.realp = malloc(N * SignalStride * sizeof Signal.realp);
	Signal.imagp = malloc(N * SignalStride * sizeof Signal.imagp);
	Observed.realp = malloc(N * ObservedStride * sizeof Observed.realp);
	Observed.imagp = malloc(N * ObservedStride * sizeof Observed.imagp);

	if (Signal.realp == NULL || Signal.imagp == NULL
		|| Observed.realp == NULL || Observed.imagp == NULL)
	{
		fprintf(stderr, "Error, failed to allocate memory.\n");
		exit(EXIT_FAILURE);
	}

	/*	Generate an input signal.  In a real application, data would of
		course be provided from an image file, sensors, or other source.
	*/
	const float Frequency0 = 300, Frequency1 = 450, Frequency2 = 775;
	const float Phase0 = .3, Phase1 = .45f, Phase2 = .775f;
	for (i = 0; i < N; ++i)
	{
		Signal.realp[i*SignalStride] =
			  cos((i * Frequency0 / N + Phase0) * TwoPi)
			+ cos((i * Frequency1 / N + Phase1) * TwoPi)
			+ cos((i * Frequency2 / N + Phase2) * TwoPi);
		Signal.imagp[i*SignalStride] =
			  sin((i * Frequency0 / N + Phase0) * TwoPi)
			+ sin((i * Frequency1 / N + Phase1) * TwoPi)
			+ sin((i * Frequency2 / N + Phase2) * TwoPi);
	}

	// Perform an FFT.
	vDSP_fft_zop(Setup, &Signal, SignalStride, &Observed, ObservedStride,
		Log2N, FFT_FORWARD);

	/*	Prepare expected results based on analytical transformation of
		the input signal.
	*/
	DSPSplitComplex Expected;
	Expected.realp = malloc(N * sizeof Expected.realp);
	Expected.imagp = malloc(N * sizeof Expected.imagp);

	if (Expected.realp == NULL || Expected.imagp == NULL)
	{
		fprintf(stderr, "Error, failed to allocate memory.\n");
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < N/2; ++i)
		Expected.realp[i] = Expected.imagp[i] = 0;

	// Add the frequencies in the signal to the expected results.
	Expected.realp[(int) Frequency0] = N * cos(Phase0 * TwoPi);
	Expected.imagp[(int) Frequency0] = N * sin(Phase0 * TwoPi);

	Expected.realp[(int) Frequency1] = N * cos(Phase1 * TwoPi);
	Expected.imagp[(int) Frequency1] = N * sin(Phase1 * TwoPi);

	Expected.realp[(int) Frequency2] = N * cos(Phase2 * TwoPi);
	Expected.imagp[(int) Frequency2] = N * sin(Phase2 * TwoPi);

	// Compare the observed results to the expected results.
	CompareComplexVectors(Expected, Observed, N);

	// Release memory.
	free(Expected.realp);
	free(Expected.imagp);

	/*	The above shows how to use the vDSP_fft_zop routine.  Now we
		will see how fast it is.
	*/

	// Time vDSP_fft_zop by itself.

	t0 = Clock();

	for (i = 0; i < Iterations; ++i)
		vDSP_fft_zop(Setup, &Signal, SignalStride, &Observed, ObservedStride,
			Log2N, FFT_FORWARD);

	t1 = Clock();

	// Average the time over all the loop iterations.
	Time = ClockToSeconds(t1, t0) / Iterations;

	printf("\tvDSP_fft_zop on %lu elements takes %g microseconds.\n",
		(unsigned long) N, Time * 1e6);

	// Release resources.
	free(Signal.realp);
	free(Signal.imagp);
	free(Observed.realp);
	free(Observed.imagp);
}