Virtual Audio Cable (VAC)
25+ years of experience. Connects audio apps together since 1998.
VAC driver component, being a WDM/KS driver, is at the lowest level in Windows audio subsystem. Most applications don't connect directly to it. Instead, they use higher-level WASAPI, MME, DirectSound and other interfaces provided by the System Audio Engine. The Engine translates applications requests to the drivers. Using such intermediate layers, an application cannot have a full control over all audio parameters. So there are some special issues and limitations. At a glance, they might look quite complex but they are easy to understand in practice.
WDM/KS audio drivers, like DirectShow filters, create KS filters that are represented by a numbers of pins. If an application or the system needs to record or play audio, it creates an instance of the specified pin. Such pin instance is associated with a data stream, and instance owner (the application or System Audio Engine) becomes a client of the driver.
Applications that use WDM/KS or DirectSound/WASAPI in exclusive mode, request a separate pin instance. If there is an available pin instance, such request succeeds, otherwise it fails. Most modern audio drivers support only a single pin instance. Therefore, several KS-aware applications can record/play simultaneously only if there are more than one pin instances supported by the particular device driver.
To allow simultaneous playback/recording possibility, System Audio Engine uses its own pin instance when the pin is accessed via WASAPI, MME, DirectSound or other higher-level interface in shared mode. When an application connects to an endpoint in shared mode, such connection request is implicitly served by System Audio Engine. If the Engine is already connected to the appropriate pin (owns a dedicated pin instance), this existing instance is shared among all applications. Otherwise, the Engine tries to create a pin instance to share. If there are no free instances, application's request is failed.
If an exclusive-mode access is requested by an application through System Audio Engine but no shared-mode connections for the appropriate pin exist (no common pin instance allocated for the Engine itself), the Engine creates its common pin instance first to allow further shared-mode connections (but there is a known bug). If the driver is single-client and supports only a single pin instance, there will be no available instances to satisfy the exclusive-mode access request. In such case, the request is either rejected or satisfied in shared-mode, depending of the parameters.
Therefore, if there are not enough available pin instances, Windows prefers shared-mode access for compatibility purposes. But direct KS access requests don't go through System Audio Engine so they can allocate the last (or even single) available pin instance. If such direct low-level request is made before a first higher-level request, System Audio Engine will be unable to create its common (shared) instance and all further higher-level requests, regardless of shared or exclusive mode, will fail.
Vice versa, if the last (or single) available pin instance has been allocated by System Audio Engine, further direct KS access requests will fail.
Creating a pin instance to serve shared mode connections, System Audio Engine needs to choose an audio format for it. Format selection is based upon application's format specified in its connection request, set of formats supported by the pin and some other rules.
In Windows 10x and 6.x, pin format is determined by the default endpoint format specified for all shared mode connections.
In Windows 5.x, the following rules are used:
MME playback: sampling rate is equal to requested, bits per sample is preferably 16 and number of channels is preferably 2 (stereo).
DirectSound playback: sampling rate is equal to a first matching from driver's set, bits per sample is preferably 16 and number of channels is preferably 2 (stereo).
MME recording and DirectSound capture: format is the same as requested except some incompatible cases (weird sampling rates, number of channels is greater than 8 etc.).
If possible pin format parameters are strongly restricted and System Audio Engine cannot use 16 bits and 2 channels, other bitness and/or number of channels can be used.
All shared-mode connections to a recording or playback device are established through System Audio Engine that uses a single common pin instance. So if your applications use shared-mode access, you will see only a single playback and/or a single recording stream in VAC Control Panel. It is because all of these applications are not VAC driver clients. They are clients of System Audio Engine. VAC even knows nothing about their existence and streaming activity; all their requests are server by System Audio Engine.
A pin instance created for System Audio Engine is often "sticky" and persists several seconds after all applications have closed their connections to Virtual Cable endpoints. You can see this in the VAC Control Panel.
Only exclusive-mode connection allows the application to become VAC client, create its own pin instance and an associated data stream. For each exclusive-mode connection, an additional stream is counted by the recording/playback stream counter.
You can experiment with various applications and formats and watch number of clients/streams in the VAC Control Panel.
Windows audio subsystem components and some applications may access VAC driver and its pins for property requests, creating no pin instance. Such connections are counted in the Driver Clients field of VAC Control Panel.
For each Virtual Cable, VAC maintains the cable format. The cable format is a common format for all cable clients (data streams). All render (output) data are converted to the cable format, mixed and then distributed among all capture (input) clients, being converted to their particular formats.
VAC selects the cable format when a Virtual Cable becomes active (gets its first client stream). As described above, there may be implicit, hidden clients like System Audio Engine whose might request a connection with a format different from the format specified by the application.
For example, default format for Virtual Cable 1 playback endpoint is set to 48000/16/2. The application requests an exclusive-mode connection through System Audio Engine, specifying 96000/24/2. Prior to satisfy this request, System Audio Engine requests a pin instance to be used for shared-mode access, specifying the default device format (48000/16/2), and VAC fixes it as the cable format. Then the Engine requests another pin instance solely for the application, specifying 96000/24/2. But the cable format remains 48000/16/2, so VAC will downsample 96000 to 48000 and cut 24-bit samples to 16-bit ones. Therefore, a default format assigned to an endpoint for shared-mode access can affect exclusive-mode access to the same endpoint.
Similarly, improper cable format range may cause quality problems in Windows 5.x. For example, is the range is set to 22050-96000/8-32/1-8, System Audio Engine creates its own common pin instance with 96000/32/8 and cable format is set to the same. If most applications use formats like 44100/16/2, 48000/16/6 or like them, there will be many unnecessary format conversions.
To prevent such issues, choose cable format range to be possibly close to your favorite format set. See format limiting rules for details.
Selecting cable format based on a first stream format, VAC driver tries to inherit stream format's channel distribution mask. But if number of channels in stream and cable formats are different (for example, if stream format limiting mode set to "Driver range"), channel mask in cable format is set to a uniform one. Uniform channel mask contains the appropriate number of contiguous "1" bits starting from least significant bit (bit 0). For example, uniform mask for eight channels will always be 0xff. Due to this technique, creating a stereo stream on a cable having number of channels range "1..1" and stream format limiting mode "Driver range", will set cable channel mask to "1" instead of usual "4" (FC).
In MME interface, endpoints are accessed by their numbers. Initially, audio application should enumerate all playback and/or recording endpoints to get their names, and then use the appropriate numbers to access desired endpoints for playback and/or recording.
As you connect or disconnect a removable audio device, change default endpoint settings, or even connect/disconnect hardware inputs/outputs (microphone, headphones, line input/output, HDMI plugs etc.), System Audio Services may rearrange endpoints of the appropriate type (playback and/or recording). In such case, some (or even all) MME endpoint numbers may change. Most MME applications (including Audio Repeater prior to its version 1.60.7) enumerate endpoints only on startup, and then use only numbers to access them. If endpoint arrangement is changed, a wrong endpoint may be accessed on the next playback and/or recording attempt.
To avoid such problems, ask the application to re-enumerate audio endpoints, if possible. Otherwise, close the application and run it again.
Windows 6.x+ systems have a common bug that prevents System Audio Engine from creating its common capture (recording) pin instance for shared-mode access if there are some active (allocated) pin instances (streams). For example, it occurs if you have started recording using KS interface (KS version of Audio Repeater, ASIO4ALL or something like) and then try to start recording using a higher-level interface (MME, DS, WASAPI) in shared mode. As a workaround, start the higher-level interface first, then start KS recording.
Starting from version 4.70, VAC driver hides active pin instance count from the Audio Engine by default, so this system bug is not exposed.