Java中的信号处理库?

37

我想计算时间序列的功率谱密度;进行一些带通、低通和高通滤波;可能还有其他一些基本操作。

是否有一个不错的开源Java库可以做到这一点?

我已经寻找了一些没有成功(例如,通过谷歌搜索“power spectral density java”或“signal processing java”,并点击链接,在Apache Commons、Sourceforge、java.net等网站中查找)。

有很多小应用程序、书籍、教程、商业产品等都不能满足我的需求。

更新:我发现 org.apache.commons.math.transform 可以进行傅里叶变换。它并没有实现功率谱密度、带通等功能,但是至少有这个开始。


1
有人知道C/C++类似的库吗? - devin
1
首先,这个问题是关于Java而不是C语言的。 :)其次,FFTW看起来有FFT功能。那么带通滤波、低通滤波、高通滤波、功率谱密度等呢?显然FFT是基础,但并不是这些操作的高级接口。 - dfrankow
https://github.com/JorenSix/TarsosDSP - kervin
1
现在距离这个问题被提出已经过去了六年。我正在寻找一个可以用于数字信号处理(在我的情况下是音乐信号处理)的Java库,以供我的研究使用。@dfrankow,你是否找到了适合你任务的Java库?或者你是否知道在你提出问题之后有任何新的Java库被引入? - vigamage
我不明白为什么这个问题被认为是“离题”的。它似乎非常相关,并且考虑到正在进行的评论,对其他人也很重要。这个问题应该重新开放以获得新的答案吗? - Hephaestus
5个回答

25

我的第一条建议是不要在Java中实现DSP。第二个建议是自己在Java中编写简单的DSP实现。


为什么不使用Java:

在过去10多年中,我有很多编写DSP代码的经验...几乎没有一个DSP代码是用Java编写的...所以请原谅我对想在Java中实现DSP的人持怀疑态度。

如果您将要进行非常规的DSP,那么就不应该使用Java。之所以在Java中实现DSP如此痛苦,是因为所有好的DSP实现都使用低级别的内存管理技巧、指针(大量的指针)、大型原始数据数组等。

为什么使用Java:

如果你正在做 简单的DSP,那么可以自己在Java中实现。像PSD和滤波器这样的简单DSP任务相对容易实现(易于实现,但速度不会很快),因为有很多实现示例和在线文档记录。

例如,我曾经在Java中实现了一个PSD函数,因为我正在在Java GUI中绘制PSD图形,所以最简单的方法就是在Java中进行性能损失,并在Java GUI中计算PSD,然后绘制它。


如何实现PSD:

PSD通常就是以分贝为单位显示的FFT的幅度。有许多学术、商业和开源示例说明如何计算以分贝为单位的FFT幅度。例如,Apache有一个Java实现可以输出FFT,然后您只需要将其转换为幅度和分贝。FFT之后的任何操作都应根据您的需求进行调整。


如何实现低通、带通滤波器:

最简单(不是最计算效率的)实现方法,在我看来是使用FIR滤波器并进行时域卷积。

卷积非常容易实现,只需要两个嵌套的循环,并且网上有数百万的示例代码。

如果你对滤波器设计一无所知,那么FIR滤波器将是比较棘手的部分。最简单的方法是使用Matlab生成你的FIR滤波器,然后将系数复制到Java中。我建议使用Matlab中的firpmord()和firpm()。在阻带方面目标是-30至-50 dB的衰减,在通带方面则为3 dB的纹波。


6
我不再从事这项工作,但从Numerical Recipes开始开发商业应用程序是不合适的。Apache Commons Math有一个FFT:http://commons.apache.org/math/userguide/transform.html。 - dfrankow
1
@dfrankow https://github.com/JorenSix/TarsosDSP 应该是一个更好的起点。 - kervin
1
我对“不要在Java中这样做”的说法感到疑惑。Java有一种很好的处理任何内存管理任务的方式,包括惊人的快速内存映射文件。虽然Java本身不允许使用原始指针,但它确实为您提供了所有高级和更安全的构造来管理内存缓冲区。简单地说,一个简单的数组可以用作循环缓冲区。只需访问数组的一个元素,而不是使用混乱的指针算术来确定它实际存储在内存中的位置。 - Gee Bee

10

我已经编写了一组Java DSP类,例如IIR滤波器:

Java DSP集合


虽然这些示例很简单,但API似乎非常灵活。谢谢! - Charlie

10
我发现了书籍Java数字信号处理和其示例源代码。您可以查看代码以确定其是否符合您的需求。
您还可以查看DSP实验室
正如duffymo和basszero在评论中提到的那样,自Java DSP出版以来,Java已经有所改变,这可能会影响某些代码示例。特别是相对较新的并发工具包可能很有用。

哇,这本书是1997年的古董了。我不确定我会推荐它。信号处理的思想没有改变,但Java确实已经改变了。 - duffymo
@duffymo:自那时以来,Java唯一的进步就是一些并发原语(因为dsp需要多线程)。通常dsp是在原始数组上进行数学运算。我和Bill一样。 - basszero
1
对我们来说更重要的是,一本书不太可能有开源许可证,因此我们将无法在我们的努力中使用它。 - dfrankow
到目前为止,所有人列出的可能性中,“DSP实验室”(一个已经死亡的开源项目)似乎具有正确的精神,但我从代码中无法确定。我不理解它的FOB,FTB,FTJ等。 - dfrankow
2
抱歉,这本书的源代码采用GPL许可证! - dfrankow
显示剩余3条评论

3

感谢提供的参考资料。老实说,我很感激。signalgo是“alpha(即完全未经测试!)”我找不到jein的源代码。英特尔不会开源。 - dfrankow

2

我找到了另一个资源,虽然它不是库:

http://www.dickbaldwin.com/tocdsp.htm

它只是一个基本的信号处理和傅里叶变换讨论,附带一些Java示例。例如,可以参考教程1478、1482、1486。不确定代码的许可证。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接