VAC 4.x binary package description
==================================





General
=======

This description is an addition to the main Virtual Audio Cable user manual
that can be located in the distribution package of any VAC version. Lite
and Trial versions can be freely downloaded from VAC home page:

https://vac.muzychenko.net/en/download.htm





Installation/uninstallation
===========================

To install the driver alone (without additional tool supplied in the
package), use INF files supplied in the package. For common
installation/uninstallation instructions, see the appropriate pages of
product user manual.

Before installation, choose proper INF/CAT files. INF/CAT files having "6x"
suffix are signed with developer's signature and intended for 6.x (Vista,
Win7/8/8.1) and 5.x (XP/2k3) Windows versions. Files with no suffix are
signed with Microsoft driver attestation signature and intended for Windows
10 and later.

VAC 4 acts as PnP device and driver and is visible in the sound/multimedia
device list in the Device Manager.

To install/remove the driver programmatically, use SetupDiXxx functions
described in the MSDN Library. UpdateDriverForPlugAndPlayDevices function
also may be used. Installation/uninstallation sequence is the same as for
any other PnP device and WDM driver.

Starting from Vista, kernel-mode drivers require publisher's digital
signature to be loaded. All VAC executables are signed by a certificate
issued for the author/developer (Evgenii Muzychenko).

If driver modules are unsigned, even the installation completes
successfully, most systems display a warning and do not load the driver.
Unsigned drivers can be loaded in "test modes" only. Please read
"Installing an Unsigned Driver During Development and Test" article how to
enable test modes:

https://docs.microsoft.com/en-us/windows-hardware/drivers/install/installing-an-unsigned-driver-during-development-and-test

You can use native signed driver modules or replace the signature with your
own, or even replace it by a self-generated test signature.

There are two ways to successfully load a driver having no valid
(authorized) signature:

- At early boot time, press F8 and select "Disable driver signature
enforcement". In this mode, Windows will not check driver signatures
during current session. But if you reboot Windows, you should press F8
and disable signature enforcement again. So you need to make selection
at every boot.

- In Windows 7 and Vista, enable Windows test-signing mode by one-time
issuing the following command:

bcdedit /set testsigning on

from a command prompt (under Administrator account). This permanently
allows Windows to load drivers signed by self-created test certificates.
After issuing bcdedit command, reboot Windows.





Setting driver/cable parameters
===============================

To set default parameters for the driver and/or cables, create appropriate
registry values in HKEY_LOCAL_MACHINE\SOFTWARE\EuMus Design\Virtual Audio
Cable\4 key before installation. For parameter description, see online
documentation or the basic VAC manual (vac.chm), "Driver and cable
configuration" chapter.

When parameter value is changed by VAC Control Panel, its value is
automatically copied to the following key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<service ID>\Parameters

Different builds have their own unique services IDs. The ID can be found in
driver INF files (ServiceId variable).

Such propagation allows the driver to access configuration parameters at
boot time. If you create/change a parameter under "Software" branch
manually, you should ensure its creation/changing under "System" branch.
Otherwise, the driver will be incorrectly configured on the next boot
because there is no access to the "Software" branch at a boot time.

However you could propagate parameter change to "System" branch by
hand, it's better to simply restart the driver that propagates
parameter values automatically.

Debugging version of VAC recognizes additional driver parameters
located in the "Debug" subkey:

GlobalPrintLevel (DWORD, 1..9) - a debug information importance level.

Most important level is 9 (error messages only). Least important level
is 1 (all possible debug information). Default level is 7. Levels of 5
and less produce a lot of debug messages that may overload the system.

To create a value controlling the debugging print level, you can use
RegEdit or create a corresponding .reg file and import it into the
Registry. In XP or later systems, you can also use the "reg" command,
entering the following string at a command prompt:

reg add HKLM\SYSTEM\CurrentControlSet\Services\<service ID>\Parameters\Debug /v GlobalPrintLevel /t REG_DWORD /d 6

/d <n> parameter specifies print level value.

To delete the registry value, enter the following command:

reg delete HKLM\SYSTEM\CurrentControlSet\Services\<service ID>\Parameters\Debug /v GlobalPrintLevel

Driver restart is required to reload Registry parameters.

To capture debug output, use a debugger or a special application like
DebugView from SysInternals. In DebugView, make sure that "Capture Kernel",
"Capture Win32" and "Capture Events" options are checked in the "Capture"
menu. If there is a massive message flow, uncheck the "Auto Scroll" option
in the "Options" menu to improve performance.





Working with cable audio devices
================================

To work with Virtual Cable audio devices, no special API is needed. The
driver exports each cable endpoints as a standard Windows audio devices
that are accessible via every Windows audio interface
(WASAPI, waveInXxx/waveOutXxx/mixerXxx, DirectSound, Kernel Streaming).

Please note that Virtual Cable is a software-only device. When you work
with a hardware device, it uses only a little amount of CPU resources to
transfer and/or transform audio data (in Vista/Win7 and later, much more
resources are used due to DRM support and creation of protected audio
path). When you work with a software device, it can only use main CPU to
transfer and/or transform audio data. So if you use improper buffering
and/or event processing algorithms, they can work fine with a hardware
device but may fail with a software one. Your buffering and timing
parameters must have a reserve enough to prevent audio stream overflow or
underflow (a starvation).





System default (preferred) device issues
========================================

In some cases, Virtual Cable endpoint becomes a system default (preferred,
or wave mapper) audio endpoint after installation. It doesn't mean that VAC
or its installer selects itself as a default endpoint. It's due to Windows
design (see VAC manual, "Installation" section, for details).

This Windows behavior is by design. There is no legal way to control it.
After adding/removal an audio device, no matter hardware or software,
Windows may change default audio endpoint assignment.

These changes can be prevented only in Windows 5.x, by explicitly selecting
default audio devices. To do it programmatically, use the
"HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper" Registry
key. The "Playback" and "Record" string values specify default/preferred
audio device names.

Starting from Windows 6, this method does not work. It may change default
audio endpoint assignments regardless of Registry settings. Windows
deveopers explain this by concern for user convenience.

To determine which devices are used by Windows as preferred for
playback/record, use waveOutMessage/waveInMessage function with
DRVM_MAPPER_PREFERRED_GET message code. Device name obtained from the Id
through waveOutGetDevCaps/waveInGetDevCaps can be placed into
Playback/Record value to make this device explicitly selected as a
preferred.

Default audio device is set on per-user basis in 5.x (XP/2k3) and on
system-basis starting from 6.x. So actions described above must be
performed at least once for each machine user in 5.x systems.





Finding device interface of VAC driver
======================================================

To interact with VAC driver, applications should obtain its device
interface path.

To do this, the application must first get a list of devices of given
class/category using SetupDiGetClassDevs function. As the ClassGuid
parameter, VAC 4 product GUID "83ed7f0e-2028-4956-b0b4-39c76fdaef1d" (in
binary form) should be specified. Flag combination (DIGCF_DEVICEINTERFACE |
DIGCF_PRESENT | DIGCF_PROFILE) must be specified as the Flags parameter.

Having device details, the application should use
SetupDiEnumDeviceInterfaces function to obtain the first interface, then
SetupDiGetDeviceInterfaceDetail function to obtain device interface path.

Particular client interfaces can be accessed by appending client interface
GUID to device interface path:

iiiiiiiiiiiiiiiiiiiiiiii\nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn

where "iiiiiiiiiiiiiiiiiiiiiiii" is the basic interface path returned by
SetupDiGetDeviceInterfaceDetail, and "nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn"
is a client interface GUID.





VAC driver API
==============

VAC driver API is intended to control driver/cable state. Its client
interface GUID is "0d13c528-a6fc-47f1-8fee-c5dd46f1fbb1".

VAC Driver API is described here:

https://vac.muzychenko.net/en/manual/api.htm

An example of using driver API version 6 can be downloaded here:

http://software.muzychenko.net/special/vac470api6.7z

Please note that some API operations require to restart the driver to be in
effect. While API interface IOCTLs work regardless of system/application
bitness, device control operations (like enabling/disabling) are not
allowed in WOW64. Therefore, in 64-bit system, only 64-bit applications can
restart a driver.





VAC KS filter API
=================

Exposing its KS filters/pins for standard KS protocols, VAC driver supports
some special functions.

VAC exposes separate KS wave/topology filters for each side
(render/capture) of each virtual cable. Special functions are implemented
for wave filters only.

The most common way to find KS wave filter interfaces is to call
SetupDiGetClassDevs function with KSCATEGORY_RENDER or KSCATEGORY_CAPTURE
class/category in ClassGuid parameter, then call
SetupDiEnumDeviceInterfaces and SetupDiGetDeviceInterfaceDetail to obtain
filter interface path for each filter. Then client application can open the
filter with CreateFile and send KS property requests with DeviceIoControl.
Internal filter property requests supported by VAC driver have property set
ID 0d13c528-a6fc-47f1-8fee-c5dd46f1fbb1.

To make sure that the interface belongs to wave filter, not to topology
one, client application may check if the interface path contains "\wave"
substring, but this is not guaranteed to be kept in the future. The only
reliable way is to open each filter in the list, send internal property
requests to it, and check the value returned by DeviceIoControl.
