2015-06-01 72 views
2

我記錄一些聲音n音訊浮動陣列和獲取錄製的音頻後,我想將其轉換回從float數組爲WAV去檢查一下。無法捕捉的15K麥克風C#n音訊中的音調頻率

我寫了一個方法,但我不確定,因爲:我嘗試記錄一個5秒鐘的15Khz音並通過fft檢查頻譜以確保15k被捕獲。 這是我的步驟:

  1. 我產生這種語氣與MATLAB首先和記錄使用Audacity,這是正確的基調。 Audacity顯示了一個很好的頻譜,在-30db的15k高峯。

  2. 我嘗試用n音訊記錄音調,並將其轉換回從記錄的float數組爲WAV去檢查它的勇氣。不幸的是,它只顯示了一些高達12k的噪音,沒有更多(在12k時爲-80db)。

這裏是正規記錄皈依數據可用時:

void myWaveIn_DataAvailable(object sender, WaveInEventArgs e) 
    { 
     myMemoryStream.Write(e.Buffer, 0, e.BytesRecorded);//this is for playing the myMemoryStream 
     for (int index = 0; index < e.BytesRecorded; index += 2)//Here I convert in a loop the stream into floating number samples 
     { 

      short sample = (short)((e.Buffer[index + 1] << 8) | 
            e.Buffer[index + 0]); 
      samples32.Add(sample/32768f);//IEEE 32 floating number 
     } 
    } 

這是我轉換回代碼:

void floatBackToStream(float[] myfloatArray) 
    { 
     short[] myShort = new short [myfloatArray.Length]; 
     myMemoryStream2 = new MemoryStream(); 
     for (int i = 0; i < myfloatArray.Length; i++) 
     { 
      myShort[i] = (short)(myfloatArray[i] * 32768f); 
      myMemoryStream2.WriteByte((byte)(myShort[i] & 255)); 
      myMemoryStream2.WriteByte((byte)(myShort[i] >> 8)); 
     } 

     myMemoryStream2.Position = 0; 
     myRaw2 = new RawSourceWaveStream(myMemoryStream2, new WaveFormat(44100,1)); 
     WaveFileWriter.CreateWaveFile("C:/Users/alon/Desktop/myRecordings/myCalibration.wav", myRaw2); 

    } 
+0

聽起來像有一個低通濾波器在某處有...什麼採樣率是您使用?你能用標準錄音軟件來錄製你的音色嗎? – Aron

+0

44.1Khz。沒有應用數字濾波器。我必須記錄NAudio課程。 – axcelenator

+0

你是如何設置WaveInEvent的?默認情況下,它使用8kHz採樣率。 – SleuthEye

回答

2

好了,所以我創建了一個帶通過濾器,在15 kHz處有峯值。因爲你說你在12kHz時有-80dB,因此峯值爲+ 80dB。如果我們想要過濾器運行良好,它需要是一個高階傳遞函數。所以這些方程可能會變得很長,但這只是乘法和加法,因此CPU不會花很長時間才能執行。我假設你的採樣率爲44.1 kHz。該方程如下:

y[k]=a7*u[k-1]+a6*u[k-2]+a5*u[k-3]+a4*u[k-4]+a3*u[k-5]+a2*u[k-6]+a1*u[k-7]+a0*u[k-8] -b7*y[k-1]-b6*y[k-2]-b5*y[k-3]-b4*y[k-4]-b3*y[k-5]-b2*y[k-6]-b1*y[k-7]-b0*y[k-8]; 

u是測得的信號和y是一個新的載體將包含15千赫的頻率。現在有估計係數2點的方法:

  1. 脈衝[弧度/秒] = 2 * PI *頻率[Hz]

這是正確的物理方程。 Coeffecients:

a7=207.5; 
a6=-578.1; 
a5=546.6; 
a4=-149.8; 
a3=-49.39; 
a2=22.21; 
a1=1.349; 
a0=0.006915; 
b7=-0.945; 
b6=0.3907; 
b5=-0.09229; 
b4=0.01363; 
b3=-0.001288; 
b2=0.00007605; 
b1=-2.567*10^(-6); 
b0=3.79*10^(-8); 
  • 的第二種方式是,假設脈衝在[Hz]的。不要責怪我,即使一些IDE程序也遵循這種不恰當的方法。
  • 對於這種情況,我們有以下係數:

    a7=3.301; 
    a6=8.643; 
    a5=-51.47; 
    a4=59.35; 
    a3=-5.498; 
    a2=-23.56; 
    a1=8.625; 
    a0=0.6114; 
    b7=-5.693; 
    b6=14.18; 
    b5=-20.19; 
    b4=17.96; 
    b3=-10.22; 
    b2=3.638; 
    b1=-0.7397; 
    b0=0.0658; 
    

    剛剛嘗試他們兩個,看看你會得到什麼。確保使用的足夠的精度數據類型,以確保我們不會乘次0.1

    +0

    你好Rafal,你是否通過matlab提取了係數?我如何計算其他頻率的係數? – axcelenator

    +0

    那麼,爲了設計濾波器,你必須對波德圖有很好的瞭解。假設您想要截斷10 kHz以上的頻率。這是脈衝2 * pi * 10000弧度/秒。接下來計算時間常數T = 1 /脈衝。簡單的濾波器就是一階動態系統,它的傳遞函數是G = k /(1 + sT),其中k是增益,應該是1. –

    +0

    所以你在Matlab中創建這個傳遞函數,使用命令tf(..) 。接下來,您必須使用c2d(...)將您的連續函數更改爲離散函數。傳遞函數等於Y/U,所以你得到一個方程Y x function_denominator = U x function_nominator。離散函數中的算子是「z」,並且倍乘z意味着前一個樣本,所以例如Y *(2 + 5z)= 2y [k] + 5y [k + 1]。將方程改爲如y [k + 1] = f(y [k],y [k-1],...,u [k],u [k-1])等形式。然後你可以準備好用任何編程語言來實現的公式。 –