Search code examples
javaaudiooutput-bufferingdelay

Playing back audio with a delay


currently i'm working on a project regarding "delayed auditory feedback" (DAF). Basically i want to record sounds from a microphone, delay it by a specific amount of time and then play it back. Using a delay around 200ms and a person with a headset, this feedback shuts down the persons ability to speak fluently. (Pretty much fun: DAF on youtube)

Right now i am trying to make this loop with SourceDataLine and TargetDataLine using a byte[]-buffer with 256 bytes. If the buffer gets bigger, so does the delay. My problem is now: I can't tell what the delay in milliseconds is.

Is there any way to calculate the real delay in ms from the buffer size? Or is there maybe another approach to get this result?

This is what my loop looks like at the moment:

private int mBufferSize; // 256
private TargetDataLine mLineOutput;
private SourceDataLine mLineInput;
public void run() {

    ... creating the DataLines and getting the lines from AudioSystem ...

    // byte buffer for audio
    byte[] data = new byte[mBufferSize];

    // start the data lines
    mLineOutput.start();
    mLineInput.start();

    // start recording and playing back
    while (running) {
        mLineOutput.read(data, 0, mBufferSize);
        mLineInput.write(data, 0, mBufferSize);
    }

    ... closing the lines and exiting ...

}

Solution

  • You can calculate the delay easily, as it's dependent on the sample rate of the audio. Assuming this is CD-quality (mono) audio, the sample rate is 44,100 samples per second. 200 milliseconds is 0.2 seconds, so 44,100 X 0.2 = 8820.

    So your audio playback needs to be delayed by 8820 samples (or 17640 bytes). If you make your recording and playback buffers exactly this size (17640 bytes) it will make your code pretty simple. As each recording buffer is filled you pass it to playback; this will achieve a playback lag of exactly one buffer's duration.