| 145 | ==== Choosing lower audio frame length ==== |
| 146 | |
| 147 | Ticket #393 (release 0.7.1) added a new media setting {{{pjsua_media_config.audio_frame_ptime}}}, or in older PJSUA-LIB, this setting is hard-coded in {{{PTIME}}} macro in {{{pjsua_media.c}}}. This setting specifies the length of audio frame in milliseconds, to be set to both the sound device and to the conference bridge. |
| 148 | |
| 149 | The previous default value is 20 milliseconds, while the default value is now set to 10 milliseconds. Changing this value from 20 to 10 milliseconds will reduce sound device latency by about 100 milliseconds and end-to-end audio latency by about 200 milliseconds. |
| 150 | |
| 151 | ==== Choose PJMEDIA_SOUND_BUFFER_COUNT carefully ==== |
| 152 | |
| 153 | The {{{PJMEDIA_SOUND_BUFFER_COUNT}}} in {{{pjmedia/config.h}}} specifies the number of audio frames in the conference bridge buffer. Larger number is better for sound stability and to accommodate sound devices that are unable to send frames in timely manner, however it would probably cause more audio delay. |
| 154 | |
| 155 | The default value was 16, and this has been changed to 6 by ticket #394 (release 0.7.1). |
| 156 | |
| 157 | ==== Optimizing Sound Device Latency ==== |
| 158 | |
| 159 | On Windows with !PortAudio backend (the default sound driver backend), with the default setting !DirectSound does have lower latency than WMME, but !DirectSound has more erratic timing. This bad timing causes additional delay in the processing of packets in the jitter buffer; there can be up to 150ms delay between packet arrival time and the time when the frame is actually picked up from the jitter buffer, regardless of jitter buffer setting. |
| 160 | |
| 161 | Release 0.7.1 has been tuned to provide better latency, with providing these settings: |
| 162 | - ticket #384 gives the ability for application to choose !DirectSound over WMME. Default is no |
| 163 | - ticket #395 adds a configuration to control the maximum buffer latency for WMME, with default value is 60 (milliseconds). For similar setting for !DirectSound, application needs to set {{{PA_MIN_LATENCY_MSEC}}} environment variable. |
| 164 | |
| 165 | With default WMME backend and 60 milliseconds buffering, application should have much better latency than with using !DirectSound. |
| 166 | |
151 | | |
152 | | You can tweak these jitter buffer settings according to your latency requirement. But please remember that the jitter buffer is not only used to accommodate network jitter, but also the jitter in the transmission by the sender. PJMEDIA for example, uses the sound device clock to drive its RTP transmission, and depending on the sound device clock accuracy, it may not [#tx-timing transmit RTP packets in timely manner], thus this needs to be accommodated by the receiver's jitter buffer. |
153 | | |
154 | | ==== Optimizing Sound Device Latency ==== |
155 | | |
156 | | The default sound device back-end in PJMEDIA is [http://www.portaudio.com PortAudio]. !PortAudio itself supports several types of host APIs, depending on the platform: |
157 | | - On Windows, it supports both !DirectSound and WMME. |
158 | | - On Linux, it supports both ALSA and OSS. |
159 | | - On MacOS X, it supports !CoreAudio |
160 | | - etc. |
161 | | |
162 | | On Windows, !DirectSound will have much better latency than WMME, so try to use !DirectSound device if possible. Unfortunately, with PJSIP version 0.7.0, WMME will be used by default. But this subsequently has been fixed with ticket #384, so version later than 0.7.0 will use !DirectSound if it is available (on Windows, that is). |
163 | | |
164 | | !PortAudio !DirectSound has the default buffering latency set to '''120''' ms. This can be overridden by application, by setting {{{PA_MIN_LATENCY_MSEC}}} environment variable. |
165 | | |
166 | | We can measure the sound device end-to-end latency using ''pjsua'', by doing this experimentation: |
167 | | 1. For this experiment, it's important to use speaker rather than headset, since we want the speaker signal to be captured by the microphone. |
168 | | 1. Run ''pjsua'' with this command line arguments: |
169 | | {{{ |
170 | | pjsua_vc6 --ec-tail 0 --rec-file latency.wav |
171 | | }}} |
172 | | 1. On ''pjsua'' menu, loop-back the microphone to the speaker, and record the microphone signal: |
173 | | {{{ |
174 | | >>> cc 0 0 |
175 | | >>> cc 0 1 |
176 | | }}} |
177 | | 1. Then tap on the microphone. You should hear it being played to the speaker too. |
178 | | 1. Quit the application: |
179 | | {{{ |
180 | | >>> q |
181 | | }}} |
182 | | |
183 | | Using WAV file waveform display, open {{{latency.wav}}} and measure the delay between the ''tap'' being captured by microphone and its echoed signal. This is the overall (microphone and speaker) delay of the sound device. |
184 | | |
185 | | On my system, an IBM X23 laptop running Windows 2000 Professional, !PortAudio !DirectSound with default settings has about 320 ms latency. Setting {{{PA_MIN_LATENCY_MSEC}}} environment variable to 20 ms will result in reduction of the latency to about 220 ms, which is consistent with the setting. |
186 | | |
187 | | With WMME backend, the overall latency is about 464 ms, using default settings. It seems that !PortAudio sets the buffering latency to 200 ms for both input and output, in {{{paDevInfo->defaultLowInputLatency}}}. Unfortunately I don't know how to override this setting in application (setting {{{PA_MIN_LATENCY_MSEC}}} environment variable doesn't seem to change the latency). But if you want to change this setting, you can change PJMEDIA's {{{pasound.c}}} and hard-code {{{inputParam.suggestedLatency}}} and {{{outputParam.suggestedLatency}}} to your requirement (for example, {{{0.020}}}). I have experimented with setting these to {{{0.020}}}, and it reduced the latency to about 254 ms. |
188 | | |
189 | | Your mileage may vary, of course. |