我必须制作一个简单的模块,我得到的长度最多为3秒的.wav文件,然后我必须首先提取幅度&那么这个文件的频率。
我是通过创建wave文件流然后阅读&amp ;;来做到这一点的。同时将数据添加到List(但命名为arr
),如下所示:
do
{ i = wav.ReadByte(); if (i != -1) { arr.Add(i); } }
while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();
然后从第44位开始,我在控制台上打印此信息或将其转储到文本文件中。现在我看到0-255范围内的整数。我知道为了获得频率,我必须使用快速傅里叶变换(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
以下的代码目前不适用于公众视图,因为它包含了我在各个点引入的大量冗余,以便可视化每个步骤的输出。
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();
}
}
答案 0 :(得分:0)
- 我的列表中的数据以当前形式表示什么?
醇>
在当前形式中,您将从文件中获取原始字节序列,但显式删除的标头除外。原始字节和相应的数据样本值之间的映射通常是非平凡的,并且根据所选择的编码方案而变化。有关详细信息,请参阅this wave file specification。
- 我首先阅读了很多关于信号采样的内容,但由于文件已经采用数字格式,所以我应该担心采样,因为我认为这只是在ADC期间完成的。另一方面,如果仍然需要完成,那么我为什么要这样做,因为我已经在使用整个文件。
醇>
实际上,wavefiles包含数字采样数据,因此您无需担心采样此数据。但是,您很可能需要知道这些数据是如何采样的,特别是使用的采样率。该信息包含在wav文件头中。
- 当前形式的数据是否已准备好用于FFT?
醇>
简单地说,不。如上所述,数据仍然是原始字节形式,并使用CopyTo
尝试将原始字节转换为double
数组,但不会删除它。
- 我现在缺少为FFT准备数据的东西是什么?
醇>
您需要将原始字节序列转换为数据样本值。如果您自己这样做,则必须考虑每个样本的位数,通道数(如果您不处理单声道,则对通道进行解交织)和编码格式(PCM,IEEE float,等等。)。 幸运的是,有几个库(例如NAudio)可以为您执行此解码。或者,您可能需要查看answers this post。