我的程序准备好进行 FFT 了吗?
Is my program ready for FFT?
我必须制作一个简单的模块,在其中获取长度最多为 3 秒的 .wav 文件,然后我必须首先从该文件中提取振幅和频率。
我这样做是通过创建波形文件流,然后读取数据并将其同时添加到列表中(但将其命名为 arr
),如下所示:
do
{ i = wav.ReadByte(); if (i != -1) { arr.Add(i); } }
while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();
然后从第 44 位开始,我要么在控制台上打印此信息,要么将其转储到文本文件中。现在我看到的是 0-255 范围内的整数。我知道为了获得频率,我必须使用快速傅立叶变换 (FFT) 将数据从时域转换到频域。
现在我的困惑是:
- 我的列表中的数据以其当前形式表示什么?
- 我读了很多关于首先对信号进行采样的内容,但是由于文件已经是数字格式,所以我应该担心采样,因为我认为它只在 ADC 期间完成。另一方面,如果它仍然需要完成,那么我为什么要这样做,因为我已经在使用整个文件。
- 当前形式的数据是否已准备好用于 FFT?
- 我现在在为 FFT 准备数据时缺少什么?
现在我只需要一种简单的方法来获取频率。如果需要的话,稍后我会添加更详细的数据提取。
我一直在研究声音处理的理论部分。但是没有一本书或文章准确地说明了 FFT 的数据准备。
我发现的一些有用的链接是:
Importing a .wav file in c# and extracting the signal an array of doubles
How to get sound data sample value in c#
Storing a wav file in an array
这篇文章支持我的逻辑,即仅在 ADC 期间需要采样
http://www.relisoft.com/science/physics/sampling.html
下面的代码不适合 PUBLIC 查看,因为现在它包含大量冗余,我在不同的点引入了这些冗余,以便可视化每个步骤的输出。
class MyClass
{
static void Main(string[] args)
{
string path = @"C:\wav_samples\";
Console.WriteLine("Select a song between 1 to 10");
string choice = Console.ReadLine();
string finalpath = path + choice+".wav";
//Creating a Stream for my .WAV File
FileStream wav = new FileStream(finalpath , FileMode.Open);
/*Declaring the ints & the list for the storage of bytes from the Stream for FFT */
int i;
List<double> arr = new List<double>();
///////////////////////////////////////////////////////////////////////////////////////////////
/*Reading Bytes from the .WAV File & then printing out the corresponding integer values */
do
{ i = wav.ReadByte();
if (i != -1)
{ arr.Add(i); } }
while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();
////////////////////////////////////////////////////////////////////////////////
//*Removing first 44 bytes of data as they include header information & other metadata*/
arr.RemoveRange(0, 44);
/*No method to find the size of list hence copying the data of list to a new array*/
double[] storage = new double[arr.Count];
arr.CopyTo(storage);
Console.WriteLine(storage.LongLength);
//Dumping results on screen or in a text file
Console.WriteLine("Do you want to get results on the screen, press 1 for yes or 2 for dumping this in a text_file in wav_sample folder");
int a = Convert.ToInt16(Console.ReadLine());
if (a == 1)
{
for (int limit = 0; limit < storage.LongLength; limit++ )
Console.WriteLine(arr[limit]);
}
if (a == 2)
{
System.IO.StreamWriter file = new System.IO.StreamWriter(path + "Results.txt", true);
for (int limit = 0; limit < storage.LongLength; limit++ )
{ file.WriteLine( storage[limit] ); }
}
Console.ReadLine();
}
}
- What does the data in my List is representing in its current form?
在当前形式中,您将从文件中获取原始字节序列,但您要明确删除的 header 除外。原始字节和对应的数据样本值之间的映射一般是non-trivial,根据选择的编码方案不同而不同。有关详细信息,请参阅 this wave file specification。
- I read a lot about Sampling the signal first, but since the file is already in a digital format so should I be worried about sampling because I think it is done during ADC only. On the other hand if it is still needed to be done, then why should I be doing that as I'm already using the whole file.
事实上,波形文件包含数字采样数据,因此您无需担心对这些数据进行采样。然而,您很可能需要知道这些数据是如何采样的,尤其是所使用的采样率。该信息包含在 wav 文件中 header.
- Is the data in its current form ready for the FFT?
简单地说,没有。正如我在上面指出的,数据仍然是原始字节形式,使用 CopyTo
尝试将原始字节转换为 double
的数组并没有削减它。
- What are the things I'm missing right now for preparing the data for FFT?
您需要将原始字节序列转换为数据样本值。如果您自己执行此操作,则必须考虑每个样本的位数、通道数(如果您不处理单声道,则对通道进行去交织)和编码格式(PCM、IEEE float、 ETC。)。
幸运的是有几个库(例如 NAudio) which can perform this decoding for you. Alternatively you may want to have a look at answers this post.
我必须制作一个简单的模块,在其中获取长度最多为 3 秒的 .wav 文件,然后我必须首先从该文件中提取振幅和频率。
我这样做是通过创建波形文件流,然后读取数据并将其同时添加到列表中(但将其命名为 arr
),如下所示:
do
{ i = wav.ReadByte(); if (i != -1) { arr.Add(i); } }
while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();
然后从第 44 位开始,我要么在控制台上打印此信息,要么将其转储到文本文件中。现在我看到的是 0-255 范围内的整数。我知道为了获得频率,我必须使用快速傅立叶变换 (FFT) 将数据从时域转换到频域。 现在我的困惑是:
- 我的列表中的数据以其当前形式表示什么?
- 我读了很多关于首先对信号进行采样的内容,但是由于文件已经是数字格式,所以我应该担心采样,因为我认为它只在 ADC 期间完成。另一方面,如果它仍然需要完成,那么我为什么要这样做,因为我已经在使用整个文件。
- 当前形式的数据是否已准备好用于 FFT?
- 我现在在为 FFT 准备数据时缺少什么?
现在我只需要一种简单的方法来获取频率。如果需要的话,稍后我会添加更详细的数据提取。
我一直在研究声音处理的理论部分。但是没有一本书或文章准确地说明了 FFT 的数据准备。
我发现的一些有用的链接是:
Importing a .wav file in c# and extracting the signal an array of doubles
How to get sound data sample value in c#
Storing a wav file in an array
这篇文章支持我的逻辑,即仅在 ADC 期间需要采样
http://www.relisoft.com/science/physics/sampling.html
下面的代码不适合 PUBLIC 查看,因为现在它包含大量冗余,我在不同的点引入了这些冗余,以便可视化每个步骤的输出。
class MyClass
{
static void Main(string[] args)
{
string path = @"C:\wav_samples\";
Console.WriteLine("Select a song between 1 to 10");
string choice = Console.ReadLine();
string finalpath = path + choice+".wav";
//Creating a Stream for my .WAV File
FileStream wav = new FileStream(finalpath , FileMode.Open);
/*Declaring the ints & the list for the storage of bytes from the Stream for FFT */
int i;
List<double> arr = new List<double>();
///////////////////////////////////////////////////////////////////////////////////////////////
/*Reading Bytes from the .WAV File & then printing out the corresponding integer values */
do
{ i = wav.ReadByte();
if (i != -1)
{ arr.Add(i); } }
while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();
////////////////////////////////////////////////////////////////////////////////
//*Removing first 44 bytes of data as they include header information & other metadata*/
arr.RemoveRange(0, 44);
/*No method to find the size of list hence copying the data of list to a new array*/
double[] storage = new double[arr.Count];
arr.CopyTo(storage);
Console.WriteLine(storage.LongLength);
//Dumping results on screen or in a text file
Console.WriteLine("Do you want to get results on the screen, press 1 for yes or 2 for dumping this in a text_file in wav_sample folder");
int a = Convert.ToInt16(Console.ReadLine());
if (a == 1)
{
for (int limit = 0; limit < storage.LongLength; limit++ )
Console.WriteLine(arr[limit]);
}
if (a == 2)
{
System.IO.StreamWriter file = new System.IO.StreamWriter(path + "Results.txt", true);
for (int limit = 0; limit < storage.LongLength; limit++ )
{ file.WriteLine( storage[limit] ); }
}
Console.ReadLine();
}
}
- What does the data in my List is representing in its current form?
在当前形式中,您将从文件中获取原始字节序列,但您要明确删除的 header 除外。原始字节和对应的数据样本值之间的映射一般是non-trivial,根据选择的编码方案不同而不同。有关详细信息,请参阅 this wave file specification。
- I read a lot about Sampling the signal first, but since the file is already in a digital format so should I be worried about sampling because I think it is done during ADC only. On the other hand if it is still needed to be done, then why should I be doing that as I'm already using the whole file.
事实上,波形文件包含数字采样数据,因此您无需担心对这些数据进行采样。然而,您很可能需要知道这些数据是如何采样的,尤其是所使用的采样率。该信息包含在 wav 文件中 header.
- Is the data in its current form ready for the FFT?
简单地说,没有。正如我在上面指出的,数据仍然是原始字节形式,使用 CopyTo
尝试将原始字节转换为 double
的数组并没有削减它。
- What are the things I'm missing right now for preparing the data for FFT?
您需要将原始字节序列转换为数据样本值。如果您自己执行此操作,则必须考虑每个样本的位数、通道数(如果您不处理单声道,则对通道进行去交织)和编码格式(PCM、IEEE float、 ETC。)。 幸运的是有几个库(例如 NAudio) which can perform this decoding for you. Alternatively you may want to have a look at answers this post.