【发布时间】:2011-03-25 02:34:43
【问题描述】:
我正在实现一个使用纯 Java 的 VOIP 应用程序。当用户不使用耳机时会出现回声问题(主要是在带有内置麦克风的笔记本电脑上)。
目前发生的情况
VOIP 应用程序的具体细节只是 Java 媒体框架的普通数据线。本质上,我想在将音频数据写入扬声器进行输出之前对音频数据进行一些数字信号处理。
public synchronized void addAudioData(byte[] ayAudioData)
{
m_oBuffer.enqueue(ayAudioData);
this.notify();
}
如您所见,音频数据到达并在缓冲区中排队。这是为了迎合狡猾的连接并允许不同的数据包大小。这也意味着在我将音频数据播放到扬声器线路之前,我可以访问任何需要的音频数据以进行任何花哨的 DSP 操作。
我已经管理了一个可以工作的回声消除器,但是它需要大量交互式用户输入,我想要一个自动回声消除器。
手动回声消除器
public static byte[] removeEcho(int iDelaySamples, float fDecay, byte[] aySamples)
{
m_awDelayBuffer = new short[iDelaySamples];
m_aySamples = new byte[aySamples.length];
m_fDecay = (float) fDecay;
System.out.println("Removing echo");
m_iDelayIndex = 0;
System.out.println("Sample length:\t" + aySamples.length);
for (int i = 0; i < aySamples.length; i += 2)
{
// update the sample
short wOldSample = getSample(aySamples, i);
// remove the echo
short wNewSample = (short) (wOldSample - fDecay * m_awDelayBuffer[m_iDelayIndex]);
setSample(m_aySamples, i, wNewSample);
// update the delay buffer
m_awDelayBuffer[m_iDelayIndex] = wNewSample;
m_iDelayIndex++;
if (m_iDelayIndex == m_awDelayBuffer.length)
{
m_iDelayIndex = 0;
}
}
return m_aySamples;
}
自适应过滤器
我已经读到adaptive filters 是要走的路。具体来说,最小均方滤波器。但是,我被困住了。上面的大多数示例代码都是用 C 和 C++ 编写的,它们不能很好地翻译成 Java。
有人对如何在 Java 中实现它们有建议吗?任何其他想法也将不胜感激。提前致谢。
【问题讨论】:
-
到目前为止,我发现这个声学回声消除指南非常非常有用:andreadrian.de/echo_cancel/index.html
标签: java echo signal-processing javasound cancellation