2012-06-15 57 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对象有精度? –