sonar_fft.cpp
00001 #include "sonar_fft.h"
00002 #include <stdio.h>
00003 #include <math.h>
00004
00005 namespace SeaBee3_Sonar {
00006
00007 bool isValidADCNumber(int adc_number) {
00008 if (adc_number == 1 || adc_number == 2 || adc_number == 3)
00009 return true;
00010
00011 return false;
00012 }
00013
00014 DataToFFT::DataToFFT(double *data1, double *data2, double *data3, const int len, const double sampling_frequency, const double target_frequency)
00015 : p_data1(data1), p_data2(data2), p_data3(data3), m_fft_length(len),
00016 m_sampling_frequency(sampling_frequency), m_target_frequency(target_frequency),
00017 m_target_bin(m_target_frequency / m_sampling_frequency * m_fft_length) {
00018 p_fft1_output = (double (*)[2]) fftw_malloc(sizeof(fftw_complex) * ( ((len)/2)+1) );
00019 p_fft2_output = (double (*)[2]) fftw_malloc(sizeof(fftw_complex) * ( ((len)/2)+1) );
00020 p_fft3_output = (double (*)[2]) fftw_malloc(sizeof(fftw_complex) * ( ((len)/2)+1) );
00021
00022 p_adc1_bin_magnitude = NULL;
00023 p_adc2_bin_magnitude = NULL;
00024 p_adc3_bin_magnitude = NULL;
00025 p_adc1_bin_phase = NULL;
00026 p_adc2_bin_phase = NULL;
00027 p_adc3_bin_phase = NULL;
00028
00029 m_fft_plan1 = fftw_plan_dft_r2c_1d(m_fft_length, p_data1, p_fft1_output, FFTW_ESTIMATE);
00030 m_fft_plan2 = fftw_plan_dft_r2c_1d(m_fft_length, p_data2, p_fft2_output, FFTW_ESTIMATE);
00031 m_fft_plan3 = fftw_plan_dft_r2c_1d(m_fft_length, p_data3, p_fft3_output, FFTW_ESTIMATE);
00032
00033 fftw_execute(m_fft_plan1);
00034 fftw_execute(m_fft_plan2);
00035 fftw_execute(m_fft_plan3);
00036 }
00037
00038 DataToFFT::~DataToFFT() {
00039 if (p_fft1_output != NULL)
00040 fftw_free(p_fft1_output);
00041 if (p_fft2_output != NULL)
00042 fftw_free(p_fft2_output);
00043 if (p_fft3_output != NULL)
00044 fftw_free(p_fft3_output);
00045
00046 if (p_adc1_bin_magnitude != NULL) {
00047 delete p_adc1_bin_magnitude;
00048 p_adc1_bin_magnitude = NULL;
00049 }
00050 if (p_adc2_bin_magnitude != NULL) {
00051 delete p_adc2_bin_magnitude;
00052 p_adc2_bin_magnitude = NULL;
00053 }
00054 if (p_adc3_bin_magnitude != NULL) {
00055 delete p_adc3_bin_magnitude;
00056 p_adc3_bin_magnitude = NULL;
00057 }
00058
00059 if (p_adc1_bin_phase != NULL) {
00060 delete p_adc1_bin_phase;
00061 p_adc1_bin_phase = NULL;
00062 }
00063 if (p_adc2_bin_phase != NULL) {
00064 delete p_adc2_bin_phase;
00065 p_adc2_bin_phase = NULL;
00066 }
00067 if (p_adc3_bin_phase != NULL) {
00068 delete p_adc3_bin_phase;
00069 p_adc3_bin_phase = NULL;
00070 }
00071
00072 fftw_destroy_plan(m_fft_plan1);
00073 fftw_destroy_plan(m_fft_plan2);
00074 fftw_destroy_plan(m_fft_plan3);
00075 }
00076
00077 double DataToFFT::getPhase(int adc_number) {
00078 if (!isValidADCNumber(adc_number))
00079 return -10.0;
00080
00081 switch (adc_number) {
00082 case 1:
00083 if (p_adc1_bin_phase == NULL) {
00084 p_adc1_bin_phase = new double(0.0);
00085 fprintf(stderr, "Target Bin: %d\n", m_target_bin);
00086 fprintf(stderr, "%10.5f, %10.5f\n", p_fft1_output[m_target_bin][1], p_fft1_output[m_target_bin][0]);
00087 *p_adc1_bin_phase = atan2(p_fft1_output[m_target_bin][1], p_fft1_output[m_target_bin][0]);
00088 }
00089 return *p_adc1_bin_phase;
00090 break;
00091 case 2:
00092 if (p_adc2_bin_phase == NULL) {
00093 p_adc2_bin_phase = new double(0.0);
00094 fprintf(stderr, "%10.5f, %10.5f\n", p_fft2_output[m_target_bin][1], p_fft2_output[m_target_bin][0]);
00095 *p_adc2_bin_phase = atan2(p_fft2_output[m_target_bin][1], p_fft2_output[m_target_bin][0]);
00096 }
00097 return *p_adc2_bin_phase;
00098 break;
00099 case 3:
00100 if (p_adc3_bin_phase == NULL) {
00101 p_adc3_bin_phase = new double(0.0);
00102 fprintf(stderr, "%10.5f, %10.5f\n", p_fft3_output[m_target_bin][1], p_fft3_output[m_target_bin][0]);
00103 *p_adc3_bin_phase = atan2(p_fft3_output[m_target_bin][1], p_fft3_output[m_target_bin][0]);
00104 }
00105 return *p_adc3_bin_phase;
00106 break;
00107 }
00108
00109
00110 return -10.0;
00111 }
00112
00113 double DataToFFT::getMagnitude(int adc_number) {
00114 if (!isValidADCNumber(adc_number))
00115 return -1.0;
00116
00117 switch (adc_number) {
00118 case 1:
00119 if (p_adc1_bin_magnitude == NULL) {
00120 p_adc1_bin_magnitude = new double(0.0);
00121 *p_adc1_bin_magnitude = p_fft1_output[m_target_bin][0] * p_fft1_output[m_target_bin][0] +
00122 p_fft1_output[m_target_bin][1] * p_fft1_output[m_target_bin][1];
00123 }
00124 return *p_adc1_bin_magnitude;
00125 break;
00126 case 2:
00127 if (p_adc2_bin_magnitude == NULL) {
00128 p_adc2_bin_magnitude = new double(0.0);
00129 *p_adc2_bin_magnitude = p_fft2_output[m_target_bin][0] * p_fft2_output[m_target_bin][0] +
00130 p_fft2_output[m_target_bin][1] * p_fft2_output[m_target_bin][1];
00131 }
00132 return *p_adc2_bin_magnitude;
00133 break;
00134 case 3:
00135 if (p_adc3_bin_magnitude == NULL) {
00136 p_adc3_bin_magnitude = new double(0.0);
00137 *p_adc3_bin_magnitude = p_fft3_output[m_target_bin][0] * p_fft3_output[m_target_bin][0] +
00138 p_fft3_output[m_target_bin][1] * p_fft3_output[m_target_bin][1];
00139 }
00140 return *p_adc1_bin_magnitude;
00141 break;
00142 }
00143
00144
00145 return -1.0;
00146 }
00147
00148 int DataToFFT::getTargetBin() {
00149 return m_target_bin;
00150 }
00151
00152 void DataToFFT::Reset() {
00153 fftw_execute(m_fft_plan1);
00154 fftw_execute(m_fft_plan2);
00155 fftw_execute(m_fft_plan3);
00156
00157 if (p_adc1_bin_magnitude != NULL) {
00158 delete p_adc1_bin_magnitude;
00159 p_adc1_bin_magnitude = NULL;
00160 }
00161 if (p_adc2_bin_magnitude != NULL) {
00162 delete p_adc2_bin_magnitude;
00163 p_adc2_bin_magnitude = NULL;
00164 }
00165 if (p_adc3_bin_magnitude != NULL) {
00166 delete p_adc3_bin_magnitude;
00167 p_adc3_bin_magnitude = NULL;
00168 }
00169
00170 if (p_adc1_bin_phase != NULL) {
00171 delete p_adc1_bin_phase;
00172 p_adc1_bin_phase = NULL;
00173 }
00174 if (p_adc2_bin_phase != NULL) {
00175 delete p_adc2_bin_phase;
00176 p_adc2_bin_phase = NULL;
00177 }
00178 if (p_adc3_bin_phase != NULL) {
00179 delete p_adc3_bin_phase;
00180 p_adc3_bin_phase = NULL;
00181 }
00182 }
00183
00184
00185 }
00186