wiki:MeasuringSoundLatency

Version 9 (modified by bennylp, 16 years ago) (diff)

--

Measuring Sound Latency

This article describes how to measure both sound device latency and overall (end-to-end) latency of pjsua. The objective of the test is to measure the audio latency introduced by both the sound device and the pjmedia framework.

Requirements

You will need:

  • pjsua executable (you can build your own, the instructions are on pjsip website).
  • a computer with microphone and loudspeaker (i.e. it's a speaker and not headset)
  • tock8.wav WAV file attached.
  • latency.c file if you don't have WAV waveform analyzer program. This file is included in PJSIP version 0.9.5 and later in pjsip-apps/src/samples directory, or if you use older PJSIP you can find the latency.c file attached. You need to build this to get the executable (again the instructions are on pjsip website).
  • optionally a WAV waveform display/analyzer to visually see the latency (such as Cool Edit on Windows)

Setup

  • Build pjsua and the latency.c
  • You MUST make sure that the loudspeaker level is set high enough so that the speaker output is fed-back to the microphone (i.e. we deliberately want to capture the audio echo)
  • You need to have a reasonable quiet room to do this test.

Measuring Sound Device Latency

This test will measure the total latency introduced by:

  • microphone and speaker device buffering (both in application layer, driver layer, and in the hardware itself)
  • conference bridge buffering

Test method (this will be done automatically by a script):

  • play a special WAV file to the speaker device, and simultaneously record directly to a WAV file
  • as the audio is played in the speaker, capture the signal in the microphone (i.e. similar to how sound echo is captured)
  • record the microphone capture to WAV file.

By looking in the recorded WAV file we should be able to know the sound device latency by measuring the interval between the recording of original signal and recording of the echo signal.

Running the Test

Run pjsua with the following command line arguments:

pjsua --no-tones --ec-tail 0 --clock-rate 8000 --snd-clock-rate 8000 --rec-file rec1.wav --play-file tock8.wav

Then once pjsua is ready, run this script below all at once (i.e. copy these and paste it to pjsua):

cc 0 0
cc 1 0
cc 1 2
cc 0 2
sleep 10000
cd 0 0
cd 1 0
cd 1 2
cd 0 2
q

The command above will play the tock8.wav file to the speaker over and over for 10 seconds, while at the same time both the WAV file and the microphone signal will be recorded to rec1.wav file. The sample rec1.wav result of my test is attached.

Analyzing the result with WAV analyzer

Here's what the recorded signal (rec1.wav) looks like in my WAV analyzer:

The highlighted area in above picture shows one cycle of recording of original signal and the echo signal.

If we zoom-in the highlighted area, it will look like this:

The strong signal (at t=0.68) is the recording of original signal directly from the input WAV file, while the weak signal (at t=0.86) is the echoed signal after the audio is played back to the speaker and captured in the microphone.

And to find out the latency, just measure the interval between original signal and echoed signal:

In this test, I found out that the latency is approximately 171 milliseconds. This value is only for the first play/echo cycle, and as most buffers in pjmedia are adaptive, the latency may grow or shrink dynamically as time progresses, hence it's probably better to use latency.c to measure the latency in more precise manner.

Analyzing the result with latency analyzer

If you don't have WAV waveform analyzer, you can measure the latency using latency.c application.

C:\> latency.exe rec1.wav
Latency average = 197
Latency minimum = 173
Latency maximum = 213
Number of data  = 9

As you can see above, measuring the latency this way has several advantages:

  • it's more automatic than manually measuring the latency with WAV analyzer
  • it should measure the latency more precisely
  • it can measure the changes in the latency (as min, max, and average) as the buffers are adapting

Measuring Overall/End?-to-end Latency

The objective of this test is to measure the overall latency of:

  • the sound device buffering in the previous test, plus the following:
  • jitter buffering
  • codec buffering
  • and everything else

Note that in order to measure the latency, we use loopback call for this test (meaning, the pjsua application will make call to itself), so this test method cannot be used to measure end-to-end latency of two pjsua instances.

Test method (note that this will be done automatically by a script):

  • make loopback call (i.e. pjsua is calling itself, so we have both caller and callee in the same pjsua instance)
  • arrange the conference bridge connection so that we have one way audio flow (i.e. the audio flow is: microphone -> caller --> loopback network --> callee --> speaker)
  • play a special WAV file to caller, and simultaneously record it to WAV file
  • audio/RTP is received by callee, which will play the received the audio to speaker
  • as the audio is played in the speaker, capture the signal in the microphone (i.e. similar to how sound echo is captured)
  • record the microphone capture to WAV file.

By looking in the recorded WAV file we should be able to know the sound device latency by measuring the interval between the recording of original signal and recording of the echo signal.

Running the Test

Run pjsua with the following command line arguments:

pjsua --no-tones --ec-tail 0 --no-vad --clock-rate 8000 --rec-file rec2.wav --play-file tock8.wav --add-codec pcmu

Then copy/paste the script below to pjsua (you need to paste them at the same time):

m
sip:localhost
sleep 100
]
a
200
sleep 1000
cd 0 4
cd 3 0
cd 0 3
cc 1 3
cc 1 2
cc 0 2
sleep 10000
cd 0 2
cd 1 2
q

The command above will make pjsua calls itself, answer the call, setup the conference bridge interconnection to record the WAV file, and do recording for 10 seconds, then quit. Once it's done, the recorded WAV file is in rec2.wav file. Please see rec2.wav from my test attached.

Analyzing the result with WAV analyzer

Measuring the latency in the recorded WAV file is the same as in the previous test. Here's my rec2.wav looks like in the WAV analyzer:

And in my measurement, I measured the delay is about 200 milliseconds. This value is only for the first play/echo cycle, and as most buffers in pjmedia are adaptive, the latency may grow or shrink dynamically as time progresses, hence it's probably better to use latency.c to measure the latency in more precise manner.

Analyzing the result with latency analyzer

Again, similar like previous test, and here's my result:

C:\> latency.exe rec2.wav
Latency average = 213
Latency minimum = 183
Latency maximum = 227
Number of data  = 9

Optimizing Latency

Please see the FAQ on audio latency on how to optimize latency.

Note on the test result

For this article, I run the test on an Windows XP SP2 desktop machine with on-board SoundMAX audio device. The test uses PJSIP version 0.9.0-trunk and default pjmedia settings (100ms buffers for both capture and playback device).

The default settings should provide reasonable trade-off between latency and stability, and as explained in FAQ on audio latency, you could always tweak the settings if you want shorter latency.

Attachments (8)

Download all attachments as: .zip