Low Latency Sound for vmWare
UPDATE 7/21/2013: Several people previously had trouble with this post due to confusion over WordPress’s annoying automatic smart quotes substitution. I’ve figured out how to disable that behavior now, so all examples should be used exactly as shown. Also added info about newer versions of VMware and host operating systems.
Anyone that uses vmWare Workstation on Windows and vmWare Fusion on the Mac together with a screen reader has probably noticed that the screen reader’s speech doesn’t respond quickly when they press key commands. Since a common behavior of screen reader users is to rapidly skim through information by repeatedly pressing a screen reader’s navigation commands, the slow response of the screen reader’s speech inside a virtual machine means that the guest operating system seems sluggish.
vmWare provides sound output for the guest operating system by simulating a virtual sound device inside the virtual machine. In the host’s operating system, vmWare uses sound in a similar manner to any other application. The vmWare application is, therefore, a proxy between the virtual sound device and the actual sound capabilities of your computer. Since vmWare is an application, it has to compete with other open applications for your computer’s resources. If multiple virtual machines are open, those virtual machines are also competing for limited resources. If the resource needs of an app other than vmWare, or another virtual machine, experiences a sudden spike, vmWare might temporarily be unable to pass sound between the virtual sound device and your computer’s physical sound device. In this situation, sound output from the virtual machine could seem to pop and click, or sound output could briefly stop altogether.
To improve this situation, vmWare buffers sound between the virtual and the physical sound devices. A buffer is an area of the computer’s memory that holds a fragment of information (sound, in this case). When a virtual machine plays sound, instead of passing sound directly between the virtual (guest) and physical (host) sound devices, the guest side of the connection places sound in to a buffer, the buffer is first allowed to fill with sound data, and, once the buffer is full, the host side begins to remove sound information from the buffer and pass it along to the physical sound device. Under normal conditions, the guest side will keep the buffer full by placing new sound information in to the buffer only as fast as the host side removes sound information. If the computer’s resources suddenly become limited, the guest side might not be able to continue placing new sound in to the buffer, but the host side can continue to remove and play sound that has already been accumulated in the buffer. Once resources are available again, the guest side can catch up by quickly placing new sound information in to the buffer until the buffer is full again. A similar process happens in reverse when a virtual machine records sound from a physical sound device.
The buffer prevents brief shortages of computing resources from causing pops and clicks in the sound of the virtual machine, but it also places all of a virtual machine’s sound on a delay. If the buffer were removed, then even brief limitations of computing resources on the host computer would cause the virtual machine’s audio to pop and click. If the buffer were extremely small, then it only would contain enough sound information to compensate for brief resource limitations. If the buffer were extremely large, then it could continue to provide glitch-free sound, even under long periods of limited computing resources, but the sound between the virtual and physical sound devices will be on an extremely long delay. The goal is to find a good compromise. The vmWare developers use a buffer that provides a fairly short delay, while being able to smooth over most brief resource limitations. Their priority is to produce glitch-free sound, not to provide the shortest delay. We, of course, have different goals.
Setting the buffer size
If you haven’t guessed by now, you’ll be making this situation better by adjusting the size of the buffer that vmWare uses for sound. Remember that the vmWare developers set the buffer size the way that it is by default to provide glitch-free audio. If you change the buffer size, you’ll probably start to notice glitches. If your computer is fast, and you aren’t using too many open applications at once, then a small buffer will result in only occasional glitches while dramatically reducing the delay. Computers have dramatically different amounts of resources, and run a wide mix of applications, so you’ll need to experiment in order to determine how small you can set the sound buffer before the glitches become too frequent to tolerate.
WARNING! Incorrectly editing your virtual machine’s configuration file can cause it to become unable to start. The easiest way to avoid this problem is to create a snapshot of the virtual machine prior to editing the configuration file. You will then easily be able to restore the snapshot to un-do any changes that you make to the configuration file if you experience problems. You can quickly access the snapshots window on VMware Workstation for Windows by pressing CTRL+m, and can access the snapshots window on VMware Fusion for Mac by pressing Command+s.
Before continuing, please be sure that your virtual machine is completely powered off. Simply suspending the virtual machine is not sufficient, as the following changes will modify the hardware of the virtual machine.
To change the size of the sound buffer used by vmWare, you must manually edit a configuration file. Each virtual machine includes a file with the VMX extension that specifies the way that the virtual machine will operate. On Windows, the VMX file will be located in the same folder as the other files used by a virtual machine. On the Mac, all of a virtual machine’s files are contained inside a bundle, and you must control-click the bundle and select “Show Package Contents” to display them. You can open the VMX file with any text editor, such as Notepad on Windows or TextEdit on the Mac. If you need further help, the vmWare knowledge base offers Tips for Editing a VMX File.
In the VMX file, you’ll find lines that look like:
category.optionName = "value"
Category selects a group of options, such as “sound” for the virtual sound device, “usb” for the virtual USB controller, etc. After the “.” is the name of the option to set. After the “=”, the value to use for the option is entered, and should be in quotes.
Disabling HD Audio
Starting with Workstation 8 on Windows and Fusion 4 on Mac, vmWare provides a new virtual sound device for some operating systems. This device simulates a RealTek ALC888 sound device. This new “HDAudio” device is a better virtual sound device in many ways. It even uses smaller sound buffers by default on Mac and Linux when compared to the older virtual sound device. However, its buffers are not as customizable as the older virtual sound device, and so I suggest that you not use it if extreme low latency is your goal.
To use the older virtual sound device, make the following changes to your VMX file.
By default, vmWare will automatically select the best virtual sound device for the guest operating system. We need manual control of this selection. Find the following line in your VMX file.
sound.autoDetect = "TRUE"
Change the “autoDetect” setting to false. Don’t forget to keep the surrounding quotes.
Next, we need to manually set the virtual sound device type. Look for a line in your VMX file similar to:
sound.virtualDev = "hdaudio"
Change it to:
sound.virtualDev = "es1371"
Booting With the New Sound Device
Now, close the VMX file and start your virtual machine. Once Windows starts, it should automatically detect the new sound device and load the drivers for it. If Windows doesn’t load the correct drivers, then you can get them to load by re-installing the VMware tools on the virtual machine. The option for re-installing the VMware tools can typically be found in the Power menu of VMware Workstation and VMware Fusion.
If your virtual machine fails to start, then you may have made a mistake while editing the VMX file. Use the snapshots window to restore the virtual machine to the state that it was in prior to this procedure, and try again.
Once Windows has started, and the new sound device has been detected, shut down Windows and re-open the VMX file.
Setting Play Buffer Size
Finally, we can set the buffer size for the virtual sound device. You probably won’t have a line in your VMX file already to do this, so you’ll need to add it. Be sure to check for one, though, as having multiple entries could cause the buffer to perform in an unexpected way.
pciSound.playBuffer = "200"
200 is the size of the buffer in milliseconds. The default size is 200 on Windows and Mac, and 100 on other host operating systems. Try using a smaller value. I’ve found that most modern Windows and Mac computers can handle a size of 30 without difficulty.
The above option adjusts the size of the playback buffer (the sound that is produced by the virtual machine). There is a separate recording buffer (sound that is recorded by the virtual machine). Compared with the default play buffer, the default record buffer is huge (more than 1 second). I’ve extensively searched online, and have even contacted vmWare directly, but, as far as anyone has been able to determine, there isn’t an option for adjusting the size of the record buffer. If you’re using conferencing applications, for example, inside a virtual machine, you’ll notice a long lag between when you say something, and when the other participants hear it. Together with the existing lag that is present in most wide area voice-over-IP situations, the total lag is substantial.
If it is important for you to reduce the size of the record buffer, then I suggest that you use the newer HD Audio virtual sound device, as its default record buffer is smaller. However, by using the HD Audio virtual sound device, you give up the capability of adjusting the size of the play buffer.
Controlling HD Audio Buffer Size
I recently received some info from vmWare development regarding the buffer sizes for the HD Audio virtual sound device. I was told that the buffer sizes are set to 80 msecs when running on a Mac host, 200 msecs when running on a Windows host, and 100 msecs for Linux and other hosts. The huge latency on Windows means that Windows users will almost always prefer the older virtual sound device.
Supposedly, the size of the buffers used by the HD Audio virtual sound device can be changed. vmWare development told me about the following VMX entry:
sound.bufferTime = "100"
100 is the buffer time in msecs.
I’ve tried this setting with vmWare Fusion on the Mac, but it doesn’t seem to have any effect. I haven’t had a chance to try it out on Windows yet.
In general, the dev from vmWare acknowledged that the HD Audio implementation is rough in many places, and that they are aware of the latency problems. Given that the HD Audio support is extremely new, both some problems, as well as future improvements, are expected.
Other HD Audio Options
There are other options for adjusting the behavior of the virtual sound devices. Most of them are listed here. Some options on that site are for the HD Audio device, some are for the ES1371 device, and some are even for the ancient SoundBlaster 16 device that was used in extremely early versions of vmWare. vmWare has never published a list, and doesn’t even seem to have internal documentation for them in many cases beyond source code comments. All of the known options have been discovered by viewing VMX files that are generated by vmWare products, through a few references in the vmWare knowledge base, and through communication with people from vmWare development and support. The situation is a mess, but will hopefully improve as the HD Audio support matures.
USB Audio Support
If none of the options in this article are able to meet your needs, be aware that there is always the option of using a USB sound device with your virtual machine. Recent versions of Workstation and Fusion have extremely good USB support. Most any USB sound device, including conferencing headsets, work well, and perform with latency as low as if they had been connected directly to a physical computer running Windows. Even some high-end multi-channel USB sound devices will work reasonably well with virtual machines.
I’m a long-time paying user of VMware products in both my personal and work life. The sound situation has improved quite a lot since I started using VMware over 10 years ago. I’ve had to regrettably harass VMware technical support on several occasions about this issue in particular, and I’m confident that this is all of the info that it is possible for VMware to provide us with for now. VMware development knows about the latency problems, but I’m unable to guess what sort of improvements they’ll be able to make in the future. VMware makes only a small portion of its income from desktop virtualization. Cloud is their primary focus now, and sound support is practically unused in cloud deployments of VMware.
If you’ve come across this post and have other observations or tricks for improving audio latency for vmWare virtual machines, please post a comment or contact me.