我想得到一个字节数组中音频字节的音高.这是我现在的代码:
byte[] wav = File.ReadAllBytes("test.wav");
for (int i = 44; i<wav.Length; i++)
{
// wav[i] is an audio byte, channel shifts every 2 bytes (I think)
}
Run Code Online (Sandbox Code Playgroud)
起初我认为wav文件是用数百或数千个块构建的,每个块都包含一个采样率,所以我试图扫描整个数组中的另一个字节序列,代表单词"WAVE",它是一个部分.块,但采样率仅在数组的开头,并且在44位之后,所有数组都只是音频数据本身.
音频字节只是十六进制值,我无法理解如何从该值获取任何信息.
更新:我已经下载了具有FFT算法的Math.NET库.这是FFT的文档:https://numerics.mathdotnet.com/api/MathNet.Numerics.IntegralTransforms/Fourier.htm 我已经阅读了所有的方法,但我不知道什么方法会做我想要的(给它几个字节的wav文件并获得它们的频率).
更新2:现在我使用Accord库进行FFT,我在youtube上找到了一个教程.这是我将音频字节转换为双数组的代码:
for (int i = 44; i<wav.Length; i+=BufferSize)
{
float currentSec = (float) audioLength / wav.Length * i;
byte[] buffer = new byte[BufferSize];
for (int j = 0; j < buffer.Length; j++)
{
if ((i + j + 1) < wav.Length)
buffer[j] = wav[i + j];
}
int SAMPLE_RESOLUTION = 16;
int BYTES_PER_POINT = SAMPLE_RESOLUTION / 8;
Int32[] vals = new Int32[buffer.Length / BYTES_PER_POINT];
double[] Ys = new double[buffer.Length / BYTES_PER_POINT];
double[] Ys2 = new double[buffer.Length / BYTES_PER_POINT];
for (int k = 0; k < Ys.Length; k++)
{
byte hByte = buffer[k * 2 + 1];
byte lByte = buffer[k * 2 + 0];
vals[k] = (int)(short)((hByte << 8) | lByte);
Ys[k] = vals[k];
}
Ys2 = FFT(Ys);
double avgFrq = AverageFromArray(Ys2);
if(lastSecond < (int) currentSec)
lastSecond = (int) currentSec;
}
Run Code Online (Sandbox Code Playgroud)
FFT功能:
private double[] FFT(double[] data)
{
double[] fft = new double[data.Length];
System.Numerics.Complex[] fftComplex = new System.Numerics.Complex[data.Length];
for (int i = 0; i < data.Length; i++)
{
fftComplex[i] = new System.Numerics.Complex(data[i], 0);
}
Accord.Math.FourierTransform.FFT(fftComplex, Accord.Math.FourierTransform.Direction.Forward);
for (int i = 0; i < data.Length; i++)
{
fft[i] = fftComplex[i].Magnitude;
}
return fft;
}
Run Code Online (Sandbox Code Playgroud)
所以要检查它是否有效我制作的wav文件只是5000Hz频率下的白噪声,但这些是我从FFT得到的结果(2048字节数组的值):https: //pastebin.com/PUq5bQTn 整个音频文件具有相同的5000Hz频率,但我的代码给我的值为605.80502914453746和4401.1090268930584
我担心你的代码(和问题)过于幼稚.
Wav文件不仅仅是音频样本的集合.有关文件格式及其结构的描述,请查看(例如)http://soundfile.sapp.org/doc/WaveFormat/.
如果你想阅读,处理,写入音频文件,那里有不同的库(例如NAudio)可以提供很多帮助.
从音频流中的1个样本中,您永远无法计算音高.为此,您需要(相对较大的)样本数并使用FFT变换计算频谱.
| 归档时间: |
|
| 查看次数: |
658 次 |
| 最近记录: |