gpt4 book ai didi

c# - 从FFT访问处理后的值

转载 作者:行者123 更新时间:2023-12-02 23:40:30 24 4
gpt4 key购买 nike

我正在尝试使用Lomont FFT来返回复数,以使用C#构建光谱图/光谱密度图。

我在理解如何从类中返回值时遇到了麻烦。
这是我到目前为止编写的似乎正在运行的代码。

    int read = 0;
Double[] data;
byte[] buffer = new byte[1024];

FileStream wave = new FileStream(args[0], FileMode.Open, FileAccess.Read);
read = wave.Read(buffer, 0, 44);
read = wave.Read(buffer, 0, 1024);
data = new Double[read];


for (int i = 0; i < read; i+=2)
{
data[i] = BitConverter.ToInt16(buffer, i) / 32768.0;
Console.WriteLine(data[i]);
}
LomontFFT LFFT = new LomontFFT();
LFFT.FFT(data, true);

我不清楚的是,如何从Lomont FFT实现中返回/访问值回到我的应用程序(控制台)?

对于C#开发而言,我还很陌生,我想我可能缺少了解如何从Lomont类实例中检索处理后的值的基本知识,甚至可能不正确地调用它。
Console.WriteLine(LFFT.A); // Returns 0
Console.WriteLine(LFFT.B); // Returns 1

我一直在寻找代码片段或如何执行此操作的说明,但是到目前为止,我并没有提出任何我所理解或解释的特定方面的信息。任何指导将不胜感激。

上面代码中提到的 data数组中保存的结果的子集可以在下面找到,根据我目前的理解,这似乎是有效的:
0.00531005859375
0.0238037109375
0.041473388671875
0.0576171875
0.07183837890625
0.083465576171875
0.092193603515625
0.097625732421875
0.099639892578125
0.098114013671875
0.0931396484375
0.0848388671875
0.07354736328125
0.05963134765625
0.043609619140625
0.026031494140625
0.007476806640625
-0.011260986328125
-0.0296630859375
-0.047027587890625
-0.062713623046875
-0.076141357421875
-0.086883544921875
-0.09454345703125
-0.098785400390625
-0.0994873046875
-0.0966796875
-0.090362548828125
-0.080810546875
-0.06842041015625
-0.05352783203125
-0.036712646484375
-0.0185546875

我实际上在尝试做什么? (透视)

我希望将波形文件加载到控制台应用程序中,并以jpg / png格式返回频谱图/光谱密度图/图像,以进行进一步处理。

我正在读取的Wave文件为单声道格式

更新1

根据所使用的FFT,我会收到略有不同的结果。

使用RealFFT
    for (int i = 0; i < read; i+=2)
{
data[i] = BitConverter.ToInt16(buffer, i) / 32768.0;
//Console.WriteLine(data[i]);
}

LomontFFT LFFT = new LomontFFT();
LFFT.RealFFT(data, true);

for (int i = 0; i < buffer.Length / 2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(data[2 * i] * data[2 * i] + data[2 * i + 1] * data[2 * i + 1]));
}

RealFFT的部分结果
0.314566983321381
0.625242818210924
0.30314888696868
0.118468857708093
0.0587697011760449
0.0369034115568654
0.0265842582236275
0.0207195964060356
0.0169601273233317
0.0143745438577886
0.012528799609089
0.0111831275153128
0.0102313284519146
0.00960198279358434
0.00920236001619566

使用FFT
    for (int i = 0; i < read; i+=2)
{
data[i] = BitConverter.ToInt16(buffer, i) / 32768.0;
//Console.WriteLine(data[i]);
}

double[] bufferB = new double[2 * data.Length];

for (int i = 0; i < data.Length; i++)
{
bufferB[2 * i] = data[i];
bufferB[2 * i + 1] = 0;
}

LomontFFT LFFT = new LomontFFT();
LFFT.FFT(bufferB, true);

for (int i = 0; i < bufferB.Length / 2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(bufferB[2 * i] * bufferB[2 * i] + bufferB[2 * i + 1] * bufferB[2 * i + 1]));
}

FFT的部分结果:
0.31456698332138
0.625242818210923
0.303148886968679
0.118468857708092
0.0587697011760447
0.0369034115568653
0.0265842582236274
0.0207195964060355
0.0169601273233317
0.0143745438577886
0.012528799609089
0.0111831275153127
0.0102313284519146
0.00960198279358439
0.00920236001619564

最佳答案

查看LomontFFT.FFT文档:

Compute the forward or inverse Fourier Transform of data, with data containing complex valued data as alternating real and imaginary parts. The length must be a power of 2. The data is modified in place.



这告诉了我们几件事。首先,该函数需要复杂值的数据,而您的数据是真实的。一个快速的解决方法是创建另一个缓冲区,其大小是原来的两倍,并将所有虚部设置为0:
double[] buffer = new double[2*data.Length];
for (int i=0; i<data.Length; i++)
{
buffer[2*i] = data[i];
buffer[2*i+1] = 0;
}

该文档还告诉我们计算已就位。这意味着在返回对 FFT的调用之后,将输入数组替换为计算结果。因此,您可以使用以下命令打印光谱:
LomontFFT LFFT = new LomontFFT();
LFFT.FFT(buffer, true);

for (int i = 0; i < buffer.Length/2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(buffer[2*i]*buffer[2*i]+buffer[2*i+1]*buffer[2*i+1]));
}

注意,由于您输入的 data是实际值,因此您也可以使用 LomontFFT.RealFFT。在这种情况下,给定稍微不同的打包规则,您将使用以下方法获得FFT结果:
LomontFFT LFFT = new LomontFFT();
LFFT.RealFFT(data, true);

System.Console.WriteLine("{0}", Math.Abs(data[0]);
for (int i = 1; i < data.Length/2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(data[2*i]*data[2*i]+data[2*i+1]*data[2*i+1]));
}
System.Console.WriteLine("{0}", Math.Abs(data[1]);

这将为您提供频谱的非冗余下半部分(与提供整个频谱的 LomontFFT.FFT不同)。同样,可以预期到关于 double1e-16精度等级的数值差异(约为 LomontFFT.FFT乘以频谱峰值)。

关于c# - 从FFT访问处理后的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39359696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com