dxd - dynax driver framework 3.0.1d223
cross platform open source driver development framework
Loading...
Searching...
No Matches
Release history

Every release adds its own entry here, newest first: what changed, in the words of what it does. A release is tagged <major>.<minor> on main - 3.0, never 3.0.0f001 - and the builds between releases carry their deployment letter and build number instead (etc/tools.sh's short(), dx::version).

3.0

The first stable release since 2.5, and the release this documentation describes.

The Windows kernel driver

kernel/wdk grew the whole WDM audio path: a PortCls adapter publishing one WaveRT subdevice per audio pin and a DMus subdevice per MIDI pin (dxd::portcls), over a USB device of its own - raw URBs, isochronous pipes, the configuration walked by the same dx::usb::audio::configure user mode uses, a boot() hook for a product's firmware handshake. The tick runs on a high resolution EX_TIMER, aligned to the bus frame counter, and the device's rings are mapped into every proxy client, each with a cursor of its own. Surprise removal, the hardware released in conclude() ahead of the remove, and the license gating the published subdevices are part of it.

Streaming

The streams of one device that always stream together form a group with one realtime thread (dx::stream::group), and the group owns every session resource. Completions stopped being a data point: the tick submits, writes and reads by the frame counter alone, a lead ahead of and behind the wire. A ring is reset by its host at its session's start and by nobody else - a service client, a pod, a proxy client or a kernel client attaches to a running ring by anchoring a dx::stream::cursor. The sample converters are keyed by the whole format, resolution, endian and alignment included (dx::stream::sample), and a clock's lock delay is waited out on both platforms.

A ring carries no transport of its own - the desc names it, as a direction: in writes the ring, out reads it - and every participant anchors at that one index, whatever its own direction. A session holds the streams it runs, its members taken in run() ahead of the thread and released at its end, and the participants sit on a lock free list, so the tick signals every mapping without taking a lock. The isochronous session's feedback ring holds two rounds at a constant lead, each charge seeding one and bundled completions swinging the lead around it. A bulk stream is data driven: its pipe keeps the platform's request ring in flight, one slot held by the completion in its callback, and whatever the ring holds goes out in one request - whole packets up to the ring's end, the packet across it bridged behind the ring, which its allocation holds the room for. The thread's last act is the clock's discharge(), where the isochronous buffers are drained and released on the thread that registered them.

Values and their stores

A promoted with a server asks it first and is born with its value otherwise - a value that could be asked with neither no longer compiles (dx::promoted). The driver's log became a preference promoted on the store and serializes like a stream desc, through the member list sinks of dx_serialize.h, so the registry and the property list both hold it resolved rather than as one opaque word.

Licensing

dx::license is one class for user mode and the kernel on every platform: it reads the certificates' DER, verifies the signature against the product's embedded root with its own SHA-256 and RSA, and evaluates type and constraints. A license binds to the device's serial number, the machine's or an ethernet address; the platform supplies the store's candidates and those identities alone - keychain, CryptoAPI, and in the kernel the registry and WMI.

The Windows user mode side

The service hosts a device tree and serves its streams over shared memory and the dxd pipe; the ASIO driver runs as its client or straight on the kernel driver, and registers itself when a device arrives - never an installer's job. The WASAPI client, the Windows MIDI Services client and the match dictionaries of both came with it. The installer is WiX 6, a merge module and an .msi without DIFx, the driver packages installed by dx::install::parser as custom actions - devices of any bus class, --restart taking them out and bringing them back on the package that ranks best in the driver store, --scan reenumerating them where they stand, and a device that fails failing the verb. The pipe carries a mutex, so a client's synchronous round trip stands alone: a connection answers in request order, and its answer names the request's kind.

MIDI

dx::midi speaks the Universal MIDI Packet: the ring of packets, the encode and decode of the MIDI 1.0 byte stream, and the group inside the word. CoreMIDI carries UMP since macOS 11 and Windows MIDI Services from the start, so both buses hand whole packets at their own timestamps.

macOS

A class compliant USB audio device is held by Apple's usbaudiod, and only a root process may take it away: the doorman daemon does exactly that and nothing else, so the driver itself stays unprivileged (dx_usb_capture.h, dx_xpc.h, dx_daemon.h), the capture request the peer's own side of it. Who that peer may be is a code signing requirement: sec::requirement builds one from its text form - team(id) the one Apple issued to a team - and sec::code checks the running peer against it. The CoreAudio server publishes a data source control per pin, and the client's IOProc holds its streams for the session and takes its interval off the HAL's buffer, with no promoted read on the real time thread.

Tooling and documentation

The test harness grew its nested command line, the streaming monitor with loopback, pattern-test and generator, unit test rows per bus and a driver level run with surprise removal; impulse-test measures an analog loop's round trip off a band limited impulse, its level calibrated to target, and a device is selected by the place it holds in the tree as --info lists it. etc/sign.ps1 is one signature path for every case - the key vault's certificate, one a CA issued to the machine, or the machine's own, which a release configuration takes only where the caller says so - with the driver packages submitted for attestation signing. etc/bootstrap.ps1 and etc/bootstrap.sh prepare a machine for building and signing, and with --server the Windows build server through it. etc/release.sh performs a stable release end to end - stamp, build every platform, notarize, publish, merge, tag and bump the sub version - and rehearses it with --dryrun; it clones the history's commits and tags without their content, writes the README.md a repository named in a release lacks, and with -l moves a submodule's pointer to the tip of its branch first. The headers carry their own documentation, the Doxygen run is warning free, and this page exists.

2.5

2025-08-26. The promoted preference gained its type safety and its alignment against the current value; a stream's sync reference reached every bus; the CoreMIDI and CoreAudio clients followed the stream layer's start and halt; a USB transaction whose size differs from the ring's line is carried.

2.4

2025-08-07. The CoreAudio server plugin's property and locking corrections, ARM64 and ARM64EC projects, and a pass over the headers' includes and their documentation.

Before 2.4

The repository's log is the record: git log 2.4 and the tags of the branches it was released from.


(c) copyright 2009 dynamic acoustics e.U. generated on

a closed source license may be obtained by requesting a written permission from dynamic acoustics e.U.
however - governmental use generally and military use especially is strictly prohibited though.