Custom binary versions of Virtual Audio Cable 4
===============================================

For basic information about VAC binary configuration, please consult the
file "binary.txt".





Principles
==========

The custom version has the same functionality as the common VAC version,
but can only be distributed and used together with a "companion" (native)
application developed by the customer. It is intended specially for
application developers, not for end users. It is built using unique
driver/device names, identifiers and parameters provided by the customer,
and works only together with customer's Native Application.

The custom version is intended to be used as an interface (bridge) between
customer's Native Application and third-party audio applications. For
example, if Native Application needs only to receive audio signals played
by third-party applications, or only to produce audio signals for
third-party applications, a single Virtual Cable is created. One cable
side/end (recording or playback) is used by Native Application, it is
called the "service" side/end. Another side/end is intented to use by
third-party applications.

If two-way audio transfer is required, two cables should be created.
Playback side/end of one of them and recording side/end of the other will
be "service" sides/ends, and the opposite sides/ends will be intended to
use by third-party applications.

By default, each cable side/end is exposed as a standard KS audio/wave
filter and pin, so it is available to all applications that use any Windows
audio interface (WASAPI, MME/WinMM, DirectSound, DirectShow, Kernel
Streaming, etc.).

The Native Application must provide specific functionality to its users,
using the custom VAC version only as an auxiliary audio stream transport
tool in particular software configurations. Applications whose primary
purpose is to give access to VAC driver for using it in arbitrary
configurations, are not allowed.





Endpoint name construction details
==================================

In Windows 6+ (since Vista), audio endpoint names are derived from bridge
pin names of KS topology filter (in VAC documenation, these bridge pins are
called "source/destination lines"), and from audio device name.

For example, you order a single-cable configuration, choosing "Dev" for
device name, "LineOut" for the destination (output) line, and "LineIn" and
"Mic" for two source (input) lines. The name of playback endpoint created
by the system will be "LineOut (Dev)", and recording endpoints will be
named "LineIn (Dev)" and "Mic (Dev)". This is by design of Windows 6+,
audio drivers cannot change this behavior. A driver only can specify its
name and source/destination line names to construct endpoint device names
from, and control which lines are currently available.

There are some rough hacking methods to override this behavior, setting
endpoint names directly in Audio Subsystem's database in the Registry, but
they may led to unpredictable results, so VAC driver doesn't use them.

When you provide a set of custom parameters, special token "%n" can be used
in device/line name template; it is replaced with cable number starting
from 1. This is useful for multi-cable configurations to create different
names from a single template.

You can also specify unique device/line names for each cable in the
configuration.

To learn more about Windows 6+ audio endpoints, see
https://msdn2.microsoft.com/en-us/library/ms678705.aspx. If this page
becomes unavailable, open http://search.microsoft.com and enter "Audio
Endpoint Devices" (with quotes).

In 5.x Windows versions, endpoint names are equal to bridge pin names
exposed by KS audio device driver. VAC driver uses changeable base name
("Virtual Cable" by default) and appends a cable number (1..N) to it.





Hidden filters/pins
===================

In the typical setup, only a single side/end of each Virtual Cable is used
by third-party applications, and another side/end (a "service" one) is used
only by the Native Application. By default, each cable exposes both render
and capture filters/pins for its both sides/ends, so both playback and
recording endpoints are visible to third-party applications.

Such cable configuration is convenient for the Native Application because
it can use any Windows audio interface to communicate with third-party
applications. But it may cause confusions: if a third-party application
selects a service endpoint, audio connection between this application and
the Native Application will not be established. Additionally, this may
confuse users who will see all service endpoints, not knowing what they are
and how to use them.

If the Native Application does not need both render and capture filters to
be exposed to Windows Audio and high-level audio interfaces, one filter in
each cable can be hidden by placing it in a separate, private
class/category, instead of standard KSCATEGORY_AUDIO, KSCATEGORY_CAPTURE or
KSCATEGORY_RENDER categories. In such case, these filters/pins will not be
enumerated by the Audio Endpoint Builder, not visible in the audio endpoint
lists, so the users and audio applications will not see them.

The Native Application can access hidden filters/pins only via KS
interface, by specifying the private class/category.

Filter hiding mode can be specified independently for each cable. For
example, the capture side can be hidden for the first cable, and the render
side can be hidden for the second. In such case, Windows and third-party
applications will see only the playback/render endpoint of the first cable,
and only the recording/capture endpoint for the second.





Special names/identifiers (visible and internal)
================================================

Each custom version has unique names and internal identifiers. All external
names (driver/product name, KS pin names, Registry key name of the
configuration tree) are provided by the customer. Internal names (driver
file, service, hardware ID etc.) are formed from the common basic name with
an unique three-character identifier. For example, for the Generic/Test
evaluation version, the unique ID is "gnr".





Custom version parameters
=========================

Each custom version has its own names and parameters. Ordering a custom
version, please specify:

- Driver manufacturer (vendor) name. If not specified, "Eugene V.
Muzychenko" will be used.

- Driver manufacturer (vendor) name GUID (used for WAVEINCAPS2/WAVEOUTCAPS2
structures). If not specified, a new random GUID will be generated.

- Contact email and/or product homepage URLs displayed in Control Panel's
"About" dialog. If these parameters are not specified, default VAC
addresses will be used.

- Vendor site URL visible in "Controller information" section of the
Audio Properties applet.

- Product name (instead of the "Virtual Audio Cable"). This name is used
for the virtual device, it will be visible in the Device Manager.
Additionally, Windows Audio will use this name to form full endpoint names
associated with the device.

- Vendor/product trademarks to be stored in the properties of the binary
executable modules. If not specified, Author's trademark information will
be used.

- An icon (16x16, 32x32, 48x48 and 256x256) displayed in VAC Control Panel
application and in "Controller information" section of the Audio Properties
applet. You may provide either a complete ICO file, a set of PNG/GIF images
of the appropriate sizes, or a single square SVG drawing. If not specified,
standard VAC icon will be used.

- 48x48 endpoint icons for destination/source lines (Line Out, Mic In, Line
In, S/PDIF In). If not specified, standard system icons will be displayed.

- Registry subkey name for driver/cable parameter set. This subkey will be
created in HKLM\Software. If not specified, vendor name will be used.
Product name will be used for the next subkey in the subtree.

- Topology (mixer) source/destination line name templates (instead of "Mic
N"/"Line N"/"S/PDIF N" for source/recording lines and "Line N" for
destination/playback one). These names will be visible only under Windows
6+ (Vista and later systems); earlier systems will use KS filter names.
Name templates may specify where to insert a cable number, for example
"MyDevice %n input" ("%n" is a placeholder for the cable number). See above
for audio endpoint name construction details.

- A base name for Kernel Streaming (KS) filters, instead of "Virtual Cable"
before the cable number. In Windows XP, these names will be visible in all
audio device lists. In later systems, they will be visible only in KS-aware
audio applications. Please note that MME interface (waveIn/waveOut) limits
device names to 32 characters.

- Topology (mixer) source line configuration (supported and initially
connected). VAC Control Panel shows them in the upper right corner.
Available lines are Mic, Line and S/PDIF. In the Control Panel, unsupported
lines are grayed out, and connected lines are checked. By default, all
lines are supported, but only Line (line input) is initially connected.

- Render/capture filter status of each cable (exposed/hidden). By default,
all cable filters/pins are exposed to third-party applications, and the
system creates audio endpoints for them. You can choose to hide cable ends
used only by your application, in order not to mislead users with their
presence; in such case, the system will not create the appropriate
endpoint(s), but your application can access these ends using KS interface
only.

- Absolute minimal and maximal values for: number of cables, sampling rate,
bits per sample, number of channels, number of pin instances (streams).
These parameters are used as absolute ranges and cannot be changed at
runtime. Stream formats outside absolute format ranges are not supported at
all.

- Default values for all variable parameters: the number of cables, cable
format range, stream format limiting mode, volume control etc. These
parameters are used only as defaults and can be changed at runtime via
Registry entries and/or driver API calls. Stream formats are limited in
accordance with stream format limiting rules for each cable separately.

- Default format parameters (sampling rate, bits per sample, number of
channels). This format will be reported as default for all cables, unless
explicitly set in Audio Properties applet (the "Advanced" tab). Default
format can be set as either common for all cables, or specific for each
cable.

- Signal transfer mode if the driver is not opened with Native Mode key
(add noise or pass silence). Hearing a noise may disturb custom version
users but using silence mode may complicate revealing of signal path if
some settings/connections are incorrect.

Parameter description can be found in VAC help file (vac.chm) contained
in basic (common) VAC trial version package. 

You only need to specify parameters different from those used in basic
(common) VAC version. In such case, other ranges and defaults will be taken
from the basic version but they can be changed in the future.

It is wise to set desired parameter values (numer of cables, format ranges,
stream format limiting mode, volume control, etc.) in the generic/test
build, and test them to ensure that these values are really suitable for
your configuration.

Copyright information of the author/developer (Eugene V. Muzychenko) is
always present inside driver binary modules (it is not displayed by
standard system windows/dialogs, so it is not visible to end users).





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

A simple command-line installer/uninstaller (wdmdrvmgr) is supplied
together with the custom binary version, in both binary/source forms. It is
intended to install a root-enumerated (software-only) virtual device and
its driver from the INF file and to uninstall any WDM device/driver.

Under 32-bit Windows, 32-bit version of wdmdrvmgr must be used. Under
64-bit Windows, use 64-bit version of wdmdrvmgr. 32-bit executable will
not work properly under 64-bit OS.

wdmdrvmgr can be invoked with a following command line:

wdmdrvmgr [<options>] -i <device Hardware ID> <INF file name>
wdmdrvmgr [<options>] -r <device Hardware ID>

Options:

-q - no info messages.
-e - no error messages.
-n - don't flush file/registry buffers.
-h <path> - Instance ID path in the "Enum" tree, instead of auto-generated.

The first form installs a device/driver from the INF file, the second
uninstalls it. Process exit code is 0 if success, or nonzero otherwise.

For device Hardware ID, see driver INF file (usually "HardwareId" variable).

On removal, wdmdrvmgr also deletes driver service, driver binary file(s),
its INF/PNF files, and driver package from Driver Store, if any.

The custom binary package contains "instrmv.cmd" script that shows how to
invoke wdmdrvmgr. Type "instrmv install" or "instrmv remove" on the command
prompt.





Native mode support and protection measures
===========================================

Custom version of VAC driver can be used only together with a customer's
application (Native Application).

Custom driver version has an unique key to identify its Native Application.
This Native Application uses a special way to open VAC driver and
authenticate itself. Such opening way is called "open in the Native Mode".
When VAC driver is opened in the Native Mode, it behaves as normal VAC
version. If VAC driver is not opened in the Native Mode, a noise is added
to transferred signal (or silence is transferred instead, if configured),
preventing use of virtual cables without Native Application.

To open the driver in the Native Mode, the Native Application must use its
Native Mode key GUID (unique for each custom version) as a client interface
GUID described in the file "binary.txt".

While VAC driver is opened in Native Mode, all cables transfer clear
signals. VAC driver remains open in the Native Mode until the handle is
closed using CloseHandle function or the Native Application terminates.

Custom builds of VAC Control Panel indicate Native Mode state by showing
"locked" or "unlocked".

Opening VAC 4 in the Native Mode only turns off its protection measures
(noise generator or silence mode). To transfer audio data, use any standard
audio interface (MME, DirectSound, Kernel Streaming) as for a regular audio
device (if the service end of the cable is exposed) or just Kernel
Streaming (if the service end is hidden).

The generic/test custom version binary package (it has "gnr" suffix in
package name) contains a simple Native Application example (vacnm), in both
binary/source forms. This example simply finds VAC 4 driver using Product
GUID of the generic/test product build
(2409b99c-deaf-4c98-8fd2-275c091dec71), appends Native Mode key GUID
(3aa9edac-0d89-4f90-978e-8fe0dbc136f6) to the interface path, opens the
driver and displays a message box on success. Until the message box is
closed, the driver remains open in the Native Mode because the process
holds driver instance handle. When the box is closed, the example closes
driver instance handle and exits.

Under 64-bit Windows, Native Application can be either 32-bit or 64-bit.
Native Mode interface works correctly in WOW64. So a single 32-bit
application may be enough for both 32- and 64-bit systems.





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

A small example (vacapi) is included to demonstrate how to use VAC driver
API. The example works as a command-line application.





Building the sources
====================

All included source code examples are tuned to be built with MS VC++ Tools
9.x (from VS 2008 or standalone) and Windows 7 (6.1.7600) SDK or WDK.
Project/solution files are taken from VS 2008.

x86 and x64 binaries can be built with any of MS VC++ Build Tools 9.x
(compiler version 15.x) or greater. Depending on the compiler/linker and
the build environment, some slight modifications of build options may be
required.

ARM64 binaries require more recent build tools (tools version 14.20 or
later, compiler version 19.xx). Visual Studio 2019 and later are suitable.

"vacapi", "vacnm" and "wdmdrvmgr" subdirs contain the file "build.cmd" that
invokes VC++ compiler and, perhaps, the linker with the appropriate
options. Of course, VC++ and Windows SDK build environments should be
initialized with the appropriate script(s) from the Build Tools
(vcvarsall.bat, vcvars32.bat, etc.).

Instead of running environment initialization scripts from VC++ tool set,
you can simply define the appropriate binary, include and library paths in
PATH, INCLUDE and LIB environment variables. The file "set_env.cmd" in
"wdmdrvmgr" subdir shows examples of settings these variables.
