我想獲取字節數組中音頻字節的音高(以Hz爲單位)。 現在這是我的代碼:從音頻字節中獲取音調或振幅等信息
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)
}
起初我以爲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;
}
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;
}
所以要檢查是否正常工作我做了一個wav文件,這只是在白噪聲5000Hz的頻率,但這些結果我從FFT獲得(2048個字節數組的值): https://pastebin.com/PUq5bQTn 整個音頻文件,具有5000Hz的頻率相同,但我的代碼給了我像值和605.80502914453746 4401.1090268930584
你是什麼意思「音頻字節的音高」?該陣列是以特定的採樣速率對音頻流進行數字捕獲 - 每個字節代表採樣時刻的幅度 - 因爲該字節沒有音高。您需要對整個陣列(或其一部分)執行某種音頻分析以獲得該時間段的音調。 – PaulF
您需要閱讀並分析標題。 – TaW
@PaulF我可以分析並獲得它的音調的最短時間段是多少?我怎樣才能做到這一點? –