2012-06-15 97 views
1

時域均衡器,我希望創造一個6(或以上)帶一個開源項目均衡器我的工作(iStudio)。我已經實現了SkypeFx均衡器,但它只有3段均衡器,但我想要一個更專業的均衡器。所以我使用Matlab自行設計了幾個濾波器,併爲樣本均衡器設計了6個ARMA濾波器。我需要實時過濾輸出。所以我繼續爲這個敘述實現一個微分方程。爲n音訊(.NET)

private double[] Filter(float[] buffer, SignalFilter filter, float filterWeight, int count) 
    { 
     double[] y = new double[buffer.Length]; 
     for (int n = 0; n < count; n++) 
     { 
      y[n] = 0.0f; 
      for (int k = 0; k < filter.B.Count; k++) 
      { 
       if (n - k >= 0) 
       { 
        y[n] = y[n] + filter.B[k] * (double)buffer[n - k]; 
       } 
      } 

      for (int k = 1; k < filter.A.Count; k++) 
      { 
       if (n - k >= 0) 
       { 
        y[n] = y[n] - filter.A[k] * y[n - k]; 
       } 
      } 
     } 

     return y; 
    } 

此功能非常簡單。在緩衝區中,我存儲實時樣本,過濾器是一個包含2個AR和MA係數陣列的類。該功能是由一個處理功能,這隻有通過所有可用的過濾器經過緩衝,總結的結果一起叫:

public void Process(float[] buffer, int offset, int count) 
    { 
     List<double[]> filtered = new List<double[]>(); 

     for (int i = 0; i < _filters.Count - 5; i++) 
     { 
      filtered.Add(Filter(buffer, _filters[i], Values[i], count)); 
     } 
     for (int i = 0; i < count; i++) 
     { 
      buffer[i] = 0.0f; 
      for (int x = 0; x < filtered.Count; x++) 
      { 
       buffer[i] += (float)(filtered[x][i] * ((Values[x] + 1)/2)); 
      } 
     } 
    } 

的代碼是有點短,但它應該是足夠了。均衡器有些作用,但它有兩個問題,第一個是它創建的延遲(可能需要優化)和聲音失真。每個已過濾的緩衝區之間只有一點點的爆炸聲。

所以我的問題是這樣的:爲什麼聲音失真,以及如何解決它?

謝謝。

+0

在http://dsp.stackexchange.com/上獲得解答可能會更好。 – earlNameless

+0

謝謝,但我想這是一個編程錯誤,因爲理論上它應該工作。 – Legoless

+0

你是否讓float值超過1.0?如果是這樣,當轉換爲16位發送到聲卡時會出現失真 –

回答

2

我通過緩存幾個值,並在方程中使用它們解決自己的問題,當一個緩衝到達和值走出當前緩衝區的指數(添加其他的IF濾波器中的功能)。每個過濾器都需要自己的緩存,所以這些值來自同一個過濾器。

private double[] Filter(float[] buffer, SignalFilter filter, int count, int index) 
    { 
     double[] y = new double[count]; 
     for (int n = 0; n < count; n++) 
     { 
      for (int k = 0; k < filter.B.Count; k++) 
      { 
       if (n - k >= 0) 
       { 
        y[n] = y[n] + filter.B[k] * buffer[n - k]; 
       } 
       else if (_cache.GetRawCache().Count > 0) 
       { 
        double cached = _cache.GetRawCache()[_cache.GetRawCache().Count + (n - k)]; 
        y[n] = y[n] + filter.B[k] * cached; 
       } 
      } 

      for (int k = 1; k < filter.A.Count; k++) 
      { 
       if (n - k >= 0) 
       { 
        y[n] = y[n] - filter.A[k] * y[n - k]; 
       } 
       else if (_cache.GetCache(index).Count > 0) 
       { 
        double cached = _cache.GetCache(index)[_cache.GetCache(index).Count + (n - k)]; 
        y[n] = y[n] - filter.A[k] * cached; 
       } 
      } 
     } 

     return y; 
    } 
+0

嗨,有趣的,但有可能對SignalFilter對象有精度? –