blob: c019bf2f708b3af9dc1a9cecf88d64acee044195 [file] [log] [blame]
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "dl/sp/src/test/gensig.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define MAX_REAL_SIGNAL_TYPE 3
#define MAX_SIGNAL_TYPE 4
int MaxSignalType(int real_only) {
return real_only ? MAX_REAL_SIGNAL_TYPE : MAX_SIGNAL_TYPE;
}
/*
* Generate a test signal and compute the theoretical FFT.
*
* The test signal is specified by |signal_type|, and the test signal
* is saved in |x| with the corresponding FFT in |fft|. The size of
* the test signal is |size|. |signalValue| is desired the amplitude
* of the test signal.
*
* If |real_only| is true, then the test signal is assumed to be real
* instead of complex, which is the default. This is only applicable
* for a |signal_type| of 0 or 3; the other signals are already real-valued.
*/
void GenerateTestSignalAndFFT(struct ComplexFloat* x,
struct ComplexFloat* fft,
int size,
int signal_type,
float signal_value,
int real_only) {
int k;
switch (signal_type) {
case 0:
/*
* Signal is a constant signal_value + i*signal_value (or just
* signal_value if real_only is true.)
*/
for (k = 0; k < size; ++k) {
x[k].Re = signal_value;
x[k].Im = real_only ? 0 : signal_value;
}
fft[0].Re = signal_value * size;
fft[0].Im = real_only ? 0 : signal_value * size;
for (k = 1; k < size; ++k) {
fft[k].Re = fft[k].Im = 0;
}
break;
case 1:
/*
* A real-valued ramp
*/
{
double factor = signal_value / (float) size;
double omega = 2 * M_PI / size;
for (k = 0; k < size; ++k) {
x[k].Re = ((k + 1)*factor);
x[k].Im = 0;
}
fft[0].Re = factor * size * (size + 1) / 2;
fft[0].Im = 0;
for (k = 1; k < size; ++k) {
double phase;
phase = omega * k;
fft[k].Re = factor * -size / 2;
fft[k].Im = factor * size / 2 * (sin(phase) / (1 - cos(phase)));
}
}
break;
case 2:
/*
* Pure real-valued sine wave, one cycle.
*/
{
double omega = 2 * M_PI / size;
for (k = 0; k < size; ++k) {
x[k].Re = signal_value * sin(omega * k);
x[k].Im = 0;
}
for (k = 0; k < size; ++k) {
fft[k].Re = 0;
fft[k].Im = 0;
}
fft[1].Im = -signal_value * (size / 2);
fft[size - 1].Im = signal_value * (size / 2);
}
break;
case 3:
/*
* The source signal is x[k] = 0 except x[1] = x[size-1] =
* -i*signal_value. The transform is one period of a pure real
* (negative) sine wave. Only defined when real_only is false.
*/
if (!real_only) {
double omega = 2 * M_PI / size;
for (k = 0; k < size; ++k) {
x[k].Re = 0;
x[k].Im = 0;
}
x[1].Im = -signal_value;
x[size-1].Im = signal_value;
for (k = 0; k < size; ++k) {
fft[k].Re = -2 * signal_value * sin(omega * k);
fft[k].Im = 0;
}
break;
}
/* Fall through if real_only */
case MAX_SIGNAL_TYPE:
default:
fprintf(stderr, "invalid signal type: %d\n", signal_type);
exit(1);
}
}