FT8CN/ft8CN/app/src/main/cpp/spectrum_data.c

125 wiersze
4.4 KiB
C
Czysty Zwykły widok Historia

#include <stdlib.h>
#include "spectrum_data.h"
static float hann_i(int i, int N) {
float x = sinf((float) M_PI * i / N);
return x * x;
}
void do_fftr(float *voiceData, int dataSize, int *fftData) {
// int block_size = FT8_SYMBOL_PERIOD * 12000; //=1920
int fftSize = FT8_SYMBOL_PERIOD * 12000; //=1920
float *window = (float *) malloc(
fftSize * sizeof(window[0])); // 申请窗空间大小是fft块大小*sizeof(windows[0])
for (int i = 0; i < fftSize; ++i) //汉宁窗
{
window[i] = hann_i(i, fftSize);
}
// 申请当前STFT分析框架nfft样本的空间。
//float *last_frame = (float *) malloc(fftSize * sizeof(last_frame[0]));
size_t fft_work_size;
// 获取FFT工作区域的大小到fft_work_size
kiss_fftr_alloc(fftSize, 0, 0, &fft_work_size);
// 申请FFT工作区域的内存
void *fft_work = malloc(fft_work_size);
kiss_fftr_cfg fft_cfg = kiss_fftr_alloc(fftSize, 0, fft_work, &fft_work_size);
// 最大块数FT8的周期时长/每个符号时长FT8:15/0.16 =93
const int max_blocks = (int) (FT8_SLOT_TIME / FT8_SYMBOL_PERIOD);
const int num_bins = (int) (12000 * FT8_SYMBOL_PERIOD / 2);
int fftOffset = 0;
int offset = 0;
float maxMag = 0;
float minMag = 65535.0f;
float mags[dataSize / 2];
for (int pos = 0; pos < dataSize / fftSize; pos++) {
kiss_fft_scalar timedata[fftSize];
kiss_fft_cpx freqdata[fftSize / 2 + 1];
for (int i = 0; i < fftSize; i++) {//fftSize=3840
timedata[i] = window[i] * voiceData[offset];//window[i] *
offset++;
}
kiss_fftr(fft_cfg, timedata, freqdata);
for (int i = 1; i < fftSize / 2 + 1; i++) {
float mag2 = sqrtf(freqdata[i].i * freqdata[i].i + freqdata[i].r * freqdata[i].r);
mags[fftOffset] = mag2;
if (maxMag < mag2) {
maxMag = mag2;
}
if (minMag > mag2) {
minMag = mag2;
}
fftOffset++;
}
float normal = (maxMag - minMag) / 256;
for (int i = 0; i < dataSize / 2; ++i) {
fftData[i] = roundf((mags[i] - minMag) / normal);
}
}
free(fft_work);
free(window);
//free(last_frame);
//free(fft_cfg);
}
void do_fftr_raw(float *voiceData, int dataSize, int *fftData) {
//int block_size = FT8_SYMBOL_PERIOD * 12000; //=1920
int fftSize = FT8_SYMBOL_PERIOD * 12000; //=1920
float *window = (float *) malloc(
fftSize * sizeof(window[0])); // 申请窗空间大小是fft块大小*sizeof(windows[0])
for (int i = 0; i < fftSize; ++i) //汉宁窗
{
window[i] = hann_i(i, fftSize);
}
// 申请当前STFT分析框架nfft样本的空间。
//float *last_frame = (float *) malloc(fftSize * sizeof(last_frame[0]));
size_t fft_work_size;
// 获取FFT工作区域的大小到fft_work_size
kiss_fftr_alloc(fftSize, 0, 0, &fft_work_size);
// 申请FFT工作区域的内存
void *fft_work = malloc(fft_work_size);
kiss_fftr_cfg fft_cfg = kiss_fftr_alloc(fftSize, 0, fft_work, &fft_work_size);
// 最大块数FT8的周期时长/每个符号时长FT8:15/0.16 =93
const int max_blocks = (int) (FT8_SLOT_TIME / FT8_SYMBOL_PERIOD);
const int num_bins = (int) (12000 * FT8_SYMBOL_PERIOD / 2);
int fftOffset = 0;
int offset = 0;
//float mags[dataSize / 2];
for (int pos = 0; pos < dataSize / fftSize; pos++) {
kiss_fft_scalar timedata[fftSize];
kiss_fft_cpx freqdata[fftSize / 2 + 1];
for (int i = 0; i < fftSize; i++) {//fftSize=3840
timedata[i] = window[i] * voiceData[offset];//window[i] *
offset++;
}
kiss_fftr(fft_cfg, timedata, freqdata);
for (int i = 1; i < fftSize / 2 + 1; i++) {
float mag2 =(freqdata[i].i * freqdata[i].i + freqdata[i].r * freqdata[i].r);
mag2= 10.0f * log10f(1E-12f + mag2);
int scaled = (int) (mag2 +20)*4;
//0~255之间
fftData[fftOffset] = (scaled < 0) ? 0 : ((scaled > 255) ? 255 : scaled);
fftOffset++;
}
// float normal = (maxMag - minMag) / 256;
// for (int i = 0; i < dataSize / 2; ++i) {
// fftData[i] = roundf((mags[i] - minMag) / normal);
// }
}
free(fft_work);
free(window);
}