Merge branch 'dg102_feature_new_process' of http://192.168.1.212:3000/zhangsheng/WLG into dg102_feature_new_process
This commit is contained in:
commit
e1fb5cc751
@ -503,7 +503,7 @@ int Uart::WaveSendCondition(char* shortAddr){
|
|||||||
sprintf(whereCon,"shortAddr = '%s' ",shortAddr);
|
sprintf(whereCon,"shortAddr = '%s' ",shortAddr);
|
||||||
vec_t vecResult = sqlite_db_ctrl::instance().GetDataSingleLine("t_shutdown_info","*",whereCon);
|
vec_t vecResult = sqlite_db_ctrl::instance().GetDataSingleLine("t_shutdown_info","*",whereCon);
|
||||||
effect = vecResult[5];
|
effect = vecResult[5];
|
||||||
if((lowSignal == 1 && atof(rssi.c_str()) < signalThreshold) || (lowBatteryLevel == 1 && fBatteryPower < batteryLevelThreshold) || effect == "1"){
|
if((lowSignal == 1 && (atof(rssi.c_str())*100) < signalThreshold) || (lowBatteryLevel == 1 && fBatteryPower < batteryLevelThreshold) || effect == "1"){
|
||||||
zlog_warn(zct, "WaveSendCondition not meet condition shortAddr = %s,rssi = %s,batteryPower = %s,effect = %s",shortAddr,rssi.c_str(),batteryPower.c_str(),effect.c_str());
|
zlog_warn(zct, "WaveSendCondition not meet condition shortAddr = %s,rssi = %s,batteryPower = %s,effect = %s",shortAddr,rssi.c_str(),batteryPower.c_str(),effect.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ unsigned char data[96000] = {0x00};
|
|||||||
unsigned char outdata[96000] = {0x00};
|
unsigned char outdata[96000] = {0x00};
|
||||||
unsigned char dealdata[96000] = {0x00};
|
unsigned char dealdata[96000] = {0x00};
|
||||||
char mqttData[1024000] = {0};
|
char mqttData[1024000] = {0};
|
||||||
|
char mqttData_vel[10240] = {0};
|
||||||
|
|
||||||
void Uart::RecordBattery(std::string &strLongAddr, DataRecvStatic &dataStatic, std::string &nowTimetamp) {
|
void Uart::RecordBattery(std::string &strLongAddr, DataRecvStatic &dataStatic, std::string &nowTimetamp) {
|
||||||
char insertSql[1024] = {0};
|
char insertSql[1024] = {0};
|
||||||
@ -106,23 +107,39 @@ void Uart::DealTriger(uint16_t ushortAdd,std::string & measurementID){
|
|||||||
sprintf(whereCon, "MeasurementID='%s' and status ='1' ", measurementID.c_str());
|
sprintf(whereCon, "MeasurementID='%s' and status ='1' ", measurementID.c_str());
|
||||||
sprintf(tablename,"t_data_%s",measurementID.c_str());
|
sprintf(tablename,"t_data_%s",measurementID.c_str());
|
||||||
vecTrigger = sqlite_db_ctrl::instance().GetDataSingleLine(" t_wave_triger_info ", " * ", whereCon);
|
vecTrigger = sqlite_db_ctrl::instance().GetDataSingleLine(" t_wave_triger_info ", " * ", whereCon);
|
||||||
|
int triger_x = 0,triger_y = 0,triger_z = 0;
|
||||||
if (vecTrigger.size() > 0){// 加速度有效值
|
if (vecTrigger.size() > 0){// 加速度有效值
|
||||||
memset(whereCon, 0x00, sizeof(whereCon));
|
memset(whereCon, 0x00, sizeof(whereCon));
|
||||||
sprintf(whereCon,"dataNodeNo = '%s' order by timeStamp desc limit 0,3;",measurementID.c_str());
|
sprintf(whereCon,"dataNodeNo = '%s' order by timeStamp desc limit 0,3;",measurementID.c_str());
|
||||||
if(vecTrigger[3] == "0"){
|
if(vecTrigger[3] == "0"){
|
||||||
array_t arrValue = sqlite_db_ctrl::instance().GetDataMultiLine(tablename, " channelID,rmsValues ", whereCon);
|
array_t arrValue = sqlite_db_ctrl::instance().GetDataMultiLine(tablename, " channelID,rmsValues ", whereCon);
|
||||||
if(arrValue.size()){
|
if(arrValue.size()){
|
||||||
|
triger_x = 0,triger_y = 0,triger_z = 0;
|
||||||
for (size_t i = 0; i < arrValue.size(); i++)
|
for (size_t i = 0; i < arrValue.size(); i++)
|
||||||
{
|
{
|
||||||
float rmsValue_f = atof(arrValue[i][1].c_str());
|
float rmsValue_f = atof(arrValue[i][1].c_str());
|
||||||
if (rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos || arrValue[i][0].find("Y") != std::string::npos)) {
|
if(rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos)){
|
||||||
zlog_warn(zct, "measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd);
|
triger_x = 1;
|
||||||
scheduler::instance().TriggerWave(ushortAdd, 0, 1);
|
zlog_warn(zct, "X measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd);
|
||||||
}else if (rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos))
|
|
||||||
{
|
|
||||||
zlog_warn(zct, "measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd);
|
|
||||||
scheduler::instance().TriggerWave(ushortAdd, 1, 0);
|
|
||||||
}
|
}
|
||||||
|
if(rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Y") != std::string::npos)) {
|
||||||
|
zlog_warn(zct, "Y measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd);
|
||||||
|
triger_y = 1;
|
||||||
|
}
|
||||||
|
if (rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos))
|
||||||
|
{
|
||||||
|
zlog_warn(zct, "Z measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd);
|
||||||
|
triger_z = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zlog_info(zct, "triger_x=%d,triger_y=%d,triger_z=%d", triger_x, triger_y, triger_z);
|
||||||
|
if((triger_x == 1 || triger_y == 1) && triger_z == 1){
|
||||||
|
scheduler::instance().TriggerWave(ushortAdd, 1, 1);
|
||||||
|
}else if((triger_x == 1 || triger_y == 1) && triger_z != 1){
|
||||||
|
scheduler::instance().TriggerWave(ushortAdd, 0, 1);
|
||||||
|
}else if(triger_x != 1 && triger_y != 1 && triger_z == 1){
|
||||||
|
scheduler::instance().TriggerWave(ushortAdd, 1, 0);
|
||||||
}
|
}
|
||||||
if (vecTrigger[4] == "0")
|
if (vecTrigger[4] == "0")
|
||||||
{
|
{
|
||||||
@ -134,17 +151,32 @@ void Uart::DealTriger(uint16_t ushortAdd,std::string & measurementID){
|
|||||||
}else if (vecTrigger[3] == "1"){// 速度有效值
|
}else if (vecTrigger[3] == "1"){// 速度有效值
|
||||||
array_t arrValue = sqlite_db_ctrl::instance().GetDataMultiLine(tablename, " channelID,integratRMS ", whereCon);
|
array_t arrValue = sqlite_db_ctrl::instance().GetDataMultiLine(tablename, " channelID,integratRMS ", whereCon);
|
||||||
if(arrValue.size()){
|
if(arrValue.size()){
|
||||||
|
triger_x = 0,triger_y = 0,triger_z = 0;
|
||||||
for (size_t i = 0; i < arrValue.size(); i++)
|
for (size_t i = 0; i < arrValue.size(); i++)
|
||||||
{
|
{
|
||||||
float integratRMS_f = atof(arrValue[i][1].c_str());
|
float integratRMS_f = atof(arrValue[i][1].c_str());
|
||||||
if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos || arrValue[i][0].find("Y") != std::string::npos)) {
|
if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos)){
|
||||||
zlog_warn(zct, "measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd);
|
zlog_warn(zct, "X measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd);
|
||||||
scheduler::instance().TriggerWave(ushortAdd, 0, 1);
|
triger_x = 1;
|
||||||
}else if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos))
|
|
||||||
{
|
|
||||||
zlog_warn(zct, "measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd);
|
|
||||||
scheduler::instance().TriggerWave(ushortAdd, 1, 0);
|
|
||||||
}
|
}
|
||||||
|
if(integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Y") != std::string::npos)) {
|
||||||
|
zlog_warn(zct, "Y measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd);
|
||||||
|
triger_y = 1;
|
||||||
|
}
|
||||||
|
if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos))
|
||||||
|
{
|
||||||
|
zlog_warn(zct, "Z measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd);
|
||||||
|
triger_z = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
zlog_info(zct, "triger_x=%d,triger_y=%d,triger_z=%d", triger_x, triger_y, triger_z);
|
||||||
|
if((triger_x == 1 || triger_y == 1) && triger_z == 1){
|
||||||
|
scheduler::instance().TriggerWave(ushortAdd, 1, 1);
|
||||||
|
}else if((triger_x == 1 || triger_y == 1) && triger_z != 1){
|
||||||
|
scheduler::instance().TriggerWave(ushortAdd, 0, 1);
|
||||||
|
}else if(triger_x != 1 && triger_y != 1 && triger_z == 1){
|
||||||
|
scheduler::instance().TriggerWave(ushortAdd, 1, 0);
|
||||||
}
|
}
|
||||||
if (vecTrigger[4] == "0")
|
if (vecTrigger[4] == "0")
|
||||||
{
|
{
|
||||||
@ -1387,11 +1419,12 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan
|
|||||||
zlog_info(zct, " product = %s,version = %d ,iChannel = %d", product.c_str(),version,iChannel);
|
zlog_info(zct, " product = %s,version = %d ,iChannel = %d", product.c_str(),version,iChannel);
|
||||||
if ((product == "02" && sampleRate == 24000 && iChannel == WAVE_Z && version == 1) ||
|
if ((product == "02" && sampleRate == 24000 && iChannel == WAVE_Z && version == 1) ||
|
||||||
(iChannel == WAVE_Z && version == 0) ||
|
(iChannel == WAVE_Z && version == 0) ||
|
||||||
((iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z) && version == 0)){
|
((iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z) && version == 0) ||
|
||||||
|
((iChannel == WAVE_X || iChannel == WAVE_Y) && version == 0)){
|
||||||
sampleRate = 25600;
|
sampleRate = 25600;
|
||||||
zlog_info(zct, " sampleRate = %d,product = %s,ACCSampleTime = %f ", sampleRate,product.c_str(),ACCSampleTime);
|
zlog_info(zct, " sampleRate = %d,product = %s,ACCSampleTime = %f ", sampleRate,product.c_str(),ACCSampleTime);
|
||||||
size_t outSize = 25600;
|
size_t outSize = 25600;
|
||||||
std::vector<float> outputData,outputData2;
|
std::vector<float> outputData,outputData2,IntegrationWave;
|
||||||
float epsilon = 1e-6f;
|
float epsilon = 1e-6f;
|
||||||
if (std::fabs(ACCSampleTime - 1) < epsilon){
|
if (std::fabs(ACCSampleTime - 1) < epsilon){
|
||||||
outputData = Calculation::fftInterpolate(vecData, outSize);
|
outputData = Calculation::fftInterpolate(vecData, outSize);
|
||||||
@ -1408,21 +1441,23 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan
|
|||||||
outSize = 32768;
|
outSize = 32768;
|
||||||
sampleRate = 25600;
|
sampleRate = 25600;
|
||||||
outputData = Calculation::fftInterpolate(vecData, outSize);
|
outputData = Calculation::fftInterpolate(vecData, outSize);
|
||||||
zlog_info(zct, " outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime);
|
zlog_info(zct, "1.28 outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime);
|
||||||
}else if(std::fabs(ACCSampleTime - 3.2) < epsilon){
|
}else if(std::fabs(ACCSampleTime - 3.2) < epsilon){
|
||||||
outSize = 8192;
|
outSize = 8192;
|
||||||
sampleRate = 2560;
|
sampleRate = 2560;
|
||||||
outputData = Calculation::fftInterpolate(vecData, outSize);
|
outputData = Calculation::fftInterpolate(vecData, outSize);
|
||||||
zlog_info(zct, " outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime);
|
|
||||||
|
zlog_info(zct, "3.2 outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime);
|
||||||
}else if(std::fabs(ACCSampleTime - 1.6) < epsilon){
|
}else if(std::fabs(ACCSampleTime - 1.6) < epsilon){
|
||||||
outSize = 5120;
|
outSize = 8192;
|
||||||
sampleRate = 5120;
|
sampleRate = 5120;
|
||||||
outputData = Calculation::fftInterpolate(vecData, outSize);
|
outputData = Calculation::fftInterpolate(vecData, outSize);
|
||||||
zlog_info(zct, " outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime);
|
zlog_info(zct, "1.6 outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime);
|
||||||
}
|
}
|
||||||
zlog_info(zct, " outputData_size %zu ", outputData.size());
|
zlog_info(zct, " outputData_size %zu ", outputData.size());
|
||||||
float mean = Calculation::mean(outputData);
|
float mean = Calculation::mean(outputData);
|
||||||
memset(mqttData,0,sizeof(mqttData));
|
memset(mqttData,0,sizeof(mqttData));
|
||||||
|
memset(mqttData_vel,0,sizeof(mqttData_vel));
|
||||||
id = 0;
|
id = 0;
|
||||||
for (size_t i = 0; i < outputData.size(); i++) {
|
for (size_t i = 0; i < outputData.size(); i++) {
|
||||||
frTemp = outputData[i] - mean;
|
frTemp = outputData[i] - mean;
|
||||||
@ -1437,6 +1472,29 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan
|
|||||||
strncpy(mqttData + id ,buf,strlen(buf));
|
strncpy(mqttData + id ,buf,strlen(buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z){
|
||||||
|
double resolution = 1 / 3.2 ;
|
||||||
|
//积分
|
||||||
|
id = 0;
|
||||||
|
std::vector<float> outputDataAC(outputData.size());
|
||||||
|
for (size_t i = 0; i < outputData.size(); i++)
|
||||||
|
{
|
||||||
|
outputDataAC[i] = outputData[i] - mean;
|
||||||
|
}
|
||||||
|
Calculation::Integration(outputDataAC, IntegrationWave, resolution);
|
||||||
|
for (size_t i = 0; i < IntegrationWave.size(); i++) {
|
||||||
|
memset(buf, 0x00, sizeof(buf));
|
||||||
|
sprintf(buf, "%.2f", IntegrationWave[i]);
|
||||||
|
if (i != IntegrationWave.size() -1){
|
||||||
|
strncpy(mqttData_vel + id ,buf,strlen(buf));
|
||||||
|
id = id + strlen(buf);
|
||||||
|
strncpy(mqttData_vel + id,",",1);
|
||||||
|
id = id + 1;
|
||||||
|
}else{
|
||||||
|
strncpy(mqttData_vel + id ,buf,strlen(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zlog_info(zct, "fopen file vecData.size : %zu end ", vecData.size());
|
zlog_info(zct, "fopen file vecData.size : %zu end ", vecData.size());
|
||||||
@ -1452,6 +1510,10 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan
|
|||||||
valWaveData["waveData"] = mqttData;
|
valWaveData["waveData"] = mqttData;
|
||||||
valWaveData["mean"] = mean;
|
valWaveData["mean"] = mean;
|
||||||
valWaveData["waveType"] = wave_type;
|
valWaveData["waveType"] = wave_type;
|
||||||
|
if(iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z){
|
||||||
|
valWaveData["waveDataVel"] = mqttData_vel;
|
||||||
|
}
|
||||||
|
valWaveData["seconds"] = ACCSampleTime;
|
||||||
Json::FastWriter WaveValue;
|
Json::FastWriter WaveValue;
|
||||||
std::string WaveData = WaveValue.write(valWaveData);
|
std::string WaveData = WaveValue.write(valWaveData);
|
||||||
|
|
||||||
|
|||||||
@ -298,54 +298,89 @@ void Calculation::Integration(std::vector<float> &vecData, std::vector<float> &r
|
|||||||
|
|
||||||
|
|
||||||
std::vector<float> Calculation::fftInterpolate(const std::vector<float>& input, size_t outputSize) {
|
std::vector<float> Calculation::fftInterpolate(const std::vector<float>& input, size_t outputSize) {
|
||||||
size_t inputSize = input.size();
|
const size_t inputSize = input.size();
|
||||||
double in[inputSize];
|
if (inputSize == 0 || outputSize == 0) {
|
||||||
for (int i = 0; i < inputSize; i++) {
|
return {};
|
||||||
in[i] = input[i];
|
|
||||||
}
|
}
|
||||||
// 1. FFTW 初始化
|
|
||||||
fftw_complex *freqDomain = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * inputSize);
|
|
||||||
fftw_complex *paddedFreqDomain = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * outputSize);
|
|
||||||
fftw_plan forwardPlan = fftw_plan_dft_r2c_1d(inputSize, in, freqDomain, FFTW_ESTIMATE);
|
|
||||||
|
|
||||||
// 2. 执行 FFT
|
// FFTW 的实数输入建议用 double
|
||||||
|
std::vector<double> in(inputSize);
|
||||||
|
for (size_t i = 0; i < inputSize; ++i) {
|
||||||
|
in[i] = static_cast<double>(input[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t inFreqSize = inputSize / 2 + 1;
|
||||||
|
const size_t outFreqSize = outputSize / 2 + 1;
|
||||||
|
|
||||||
|
fftw_complex* freqIn = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * inFreqSize);
|
||||||
|
fftw_complex* freqOut = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * outFreqSize);
|
||||||
|
|
||||||
|
if (!freqIn || !freqOut) {
|
||||||
|
if (freqIn) fftw_free(freqIn);
|
||||||
|
if (freqOut) fftw_free(freqOut);
|
||||||
|
throw std::runtime_error("FFTW malloc failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清零输出频谱
|
||||||
|
for (size_t i = 0; i < outFreqSize; ++i) {
|
||||||
|
freqOut[i][0] = 0.0;
|
||||||
|
freqOut[i][1] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fftw_plan forwardPlan = fftw_plan_dft_r2c_1d(
|
||||||
|
static_cast<int>(inputSize),
|
||||||
|
in.data(),
|
||||||
|
freqIn,
|
||||||
|
FFTW_ESTIMATE
|
||||||
|
);
|
||||||
|
|
||||||
fftw_execute(forwardPlan);
|
fftw_execute(forwardPlan);
|
||||||
|
|
||||||
// 3. 频域插值:扩展频谱
|
// 只复制半谱里能容纳的低频部分
|
||||||
size_t halfSize = inputSize / 2 + 1; // 实数FFT的对称部分
|
// 对于重采样,保留共同可表示的频率范围
|
||||||
for (size_t i = 0; i < halfSize; ++i) {
|
size_t copyBins = std::min(inFreqSize, outFreqSize);
|
||||||
paddedFreqDomain[i][0] = freqDomain[i][0]; // 实部
|
|
||||||
paddedFreqDomain[i][1] = freqDomain[i][1]; // 虚部
|
// Nyquist 点要小心,但先按通用方式复制可用部分
|
||||||
}
|
for (size_t k = 0; k < copyBins; ++k) {
|
||||||
for (size_t i = halfSize; i < outputSize - halfSize; ++i) {
|
freqOut[k][0] = freqIn[k][0];
|
||||||
paddedFreqDomain[i][0] = 0.0; // 实部填零
|
freqOut[k][1] = freqIn[k][1];
|
||||||
paddedFreqDomain[i][1] = 0.0; // 虚部填零
|
|
||||||
}
|
|
||||||
for (size_t i = outputSize - halfSize; i < outputSize; ++i) {
|
|
||||||
paddedFreqDomain[i][0] = freqDomain[inputSize - (outputSize - i)][0];
|
|
||||||
paddedFreqDomain[i][1] = freqDomain[inputSize - (outputSize - i)][1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. IFFT 变换回时域
|
// 如果是偶数长度,Nyquist 点必须是纯实数
|
||||||
std::vector<double> output(outputSize);
|
if (outputSize % 2 == 0) {
|
||||||
fftw_plan inversePlan = fftw_plan_dft_c2r_1d(outputSize, paddedFreqDomain, output.data(), FFTW_ESTIMATE);
|
freqOut[outFreqSize - 1][1] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> out(outputSize, 0.0);
|
||||||
|
|
||||||
|
fftw_plan inversePlan = fftw_plan_dft_c2r_1d(
|
||||||
|
static_cast<int>(outputSize),
|
||||||
|
freqOut,
|
||||||
|
out.data(),
|
||||||
|
FFTW_ESTIMATE
|
||||||
|
);
|
||||||
|
|
||||||
fftw_execute(inversePlan);
|
fftw_execute(inversePlan);
|
||||||
|
|
||||||
// 5. 缩放输出结果
|
// FFTW 的 c2r 没有自动归一化
|
||||||
for (double& val : output) {
|
// 这里除以 outputSize 是 IFFT 归一化
|
||||||
val /= outputSize;
|
// 再乘 outputSize/inputSize 用于尽量保持幅值一致
|
||||||
|
const double scale = 1.0 / static_cast<double>(inputSize);
|
||||||
|
for (size_t i = 0; i < outputSize; ++i) {
|
||||||
|
out[i] *= scale;
|
||||||
}
|
}
|
||||||
std::vector<float> output2(outputSize);
|
|
||||||
for (int i = 0; i < outputSize; i++) {
|
std::vector<float> result(outputSize);
|
||||||
output2[i] = output[i];
|
for (size_t i = 0; i < outputSize; ++i) {
|
||||||
|
result[i] = static_cast<float>(out[i]);
|
||||||
}
|
}
|
||||||
// 清理 FFTW
|
|
||||||
fftw_destroy_plan(forwardPlan);
|
fftw_destroy_plan(forwardPlan);
|
||||||
fftw_destroy_plan(inversePlan);
|
fftw_destroy_plan(inversePlan);
|
||||||
fftw_free(freqDomain);
|
fftw_free(freqIn);
|
||||||
fftw_free(paddedFreqDomain);
|
fftw_free(freqOut);
|
||||||
|
|
||||||
return output2;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Calculation::freqDomainDecimateFFTW(const std::vector<float>& input,
|
bool Calculation::freqDomainDecimateFFTW(const std::vector<float>& input,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user