【问题标题】:Digital filtering in java Android is too slowjava Android中的数字过滤太慢了
【发布时间】:2018-02-04 23:35:44
【问题描述】:

我正在尝试在 Android 中实现音频信号的实时数字过滤。我为高通滤波器使用了标准代码:

void doFilter(final short in[], short out[], int sizeIn) {
    int i, j;

    for (i = 0; i < sizeIn; i++) {
        out[i] = 0;
        for (j = 0; j < size; j++)
            if (i >= j) out[i] += H[j] * in[i - j];
            else out[i] += H[j] * dataTail[i + size - j];
    }
    System.arraycopy(in, sizeIn - size - 1, dataTail, 0, size);
}

问题在于,这个代码运行非常缓慢来实时过滤来自麦克风的信号:200ms 用于100 samples 的过滤器和长1700 samples 的输入数据。是什么原因以及解决这个问题的方法是什么? 建议,请完成用于快速信号过滤的库。谢谢。

【问题讨论】:

  • 您可以使用变量来计算总和并分配给第二个(内部)循环之外的 out[i]。但我不确定仅此一项是否有帮助。
  • @h22 我不太明白这有什么帮助
  • 数组成员 out[i] 访问可能比单个变量访问要慢,并且您在循环中执行了很多次。我不确定 Android Java 编译器是否足够聪明来优化它。
  • 在可接受范围内需要多快? dataTail 到底是什么(我理解这个概念,但在这种情况下它的用途是未知的)?您是否对缓冲区队列中的缓冲区进行操作?如果不是,为什么不呢?你确定这个卷积是瓶颈吗?如果你不执行卷积,一切都按预期工作吗?这个算法可以做得更快,但只是在一定程度上。如果你离目标很远,并且没有其他改进的选择,hotpaw2 可能是正确的,你必须换档。
  • @Dave 40 ms 是可接受的最大范围。 DataTail 是前一个数据缓冲区的尾部。它是输入数据的连续性所必需的。我已经完全确信 Java 不适合解决我的问题,现在我正在寻找一个现成的 JNI 库。

标签: java android signal-processing digital-filter


【解决方案1】:

与 C/C++ 相比,Java 对于大量计算非常慢,请考虑使用 Android NDK for JNI 以 C/C++ 编译您的主要逻辑。

【讨论】:

  • 我是 JNI 的新手。您可以推荐哪些现成的库来过滤信号?
  • 抱歉,我还没有进行任何类型的信号过滤。如果您了解基本的 C 编程,那么实现像您在问题中发布的简单功能真的很容易。在google中搜索库,如果找不到,请学习Android JNI。
【解决方案2】:

对于长度为 100 的 FIR 滤波器内核,您可能需要使用零填充 FFT/IFFT 重叠添加/保存快速卷积方法,而不是时域卷积。最好在 JNI 中用 C 语言编写。我不知道图书馆,但算法可能会在一些 DSP 教科书中解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多