Alex Rivera | Logout

Acoustic echo cancellation in Java

Asked 2010-08-04T06:37:11.927
9

I'm implementing a VOIP application that uses pure Java. There is an echo problem that occurs when users do not use headsets (mostly on laptops with built-in microphones).

What currently happens

The nuts and bolts of the VOIP application is just the plain datalines of Java's media framework. Essentially, I'd like to perform some digital signal processing on audio data before I write it to the speaker for output.

  public synchronized void addAudioData(byte[] ayAudioData)
  {
    m_oBuffer.enqueue(ayAudioData);
    this.notify();
  }

As you can see the audio data arrives and is enqueued in a buffer. This is to cater for dodgy connections and to allow for different packet sizes. It also means I have access to as much audio data as I need for any fancy DSP operations before I play the audio data to the speaker line.

I've managed one echo canceller that does work, however it requires a lot of interactive user input and I'd like to have an automatic echo canceller.

Manual echo canceller

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;
  }

                    
                    
                    
Edit
Report

2 Answers

4

Use the Speex AEC. It's open source, it's written in C (use it with JNI), and it works. I've successfully used it in 2 different VoIP applications and it gets most of the echo cancelled.

answered 2011-03-09T14:21:26.193
1

This is a very complex area and to get a usable AEC solution working you'll need to do quite a bit of R&D. All the good AECs are proprietary, and there's a lot more to echo cancellation than just implementing an adaptive filter such as LMS. I suggest you develop your echo cancellation algorithm initially using MATLAB (or Octave) - when you have something that appears to work reasonably well with "real world" telecomms then you can implement the algorithm in C and test/evaluate it in real-time. Once this is working you can use JNI to call the C implementation from Java.

answered 2010-08-04T06:45:04.667

Your Answer