ACX device enumeration

This topic discusses ACX device enumeration, startup and shutdown, and device rebalance. For a general overview of ACX, see ACX audio class extensions overview. For information about ACX power management and PnP, see ACX power management.

ACX device enumeration and startup for static audio devices

To learn about how ACX startup works, the following scenario will be described.

  • An audio device is represented by a single circuit.
  • An audio/circuit lifetime is tied to the PnP device lifetime.
  • A single device can create multiple circuits for different audio devices.
  • KMDF kernel-mode environment.

The sequence of start up is:

ACX Stream Add

  • ACX Stream Add (instance) on ACX Circuit (ACX callback on ACX circuits) – invoked at any time after the WDF self-managed I/O Init or Restart has been invoked and device is in D0. Circuit-scoped.
    • Input: AcxStreamInit context, ACXCIRCUIT.
    • Add callbacks.
    • Create an AcxStream (instance).
    • Optionally do any post stream Instance init.
    • On return, ACX activates this stream instance, and since in this scenario is the only one on the audio path, it allows stream messages to go through.

ACX device enumeration and startup for dynamic audio devices

In this scenario the following are assumed.

  • Dynamic audio support (create/delete audio devices at run-time).
  • Device lifetime is not tied to the circuit lifetime.
  • A single device can create multiple circuits for different audio devices.
  • Piggybacks on the simple static pattern described above by only adding elements specific to dynamic pattern.
  • Makes use of child raw PDOs.
  • KMDF kernel-mode environment.

The sequence of start up for this scenario is:

  • WDM DriverEntry. Driver-scoped.

    • Init tracing.
    • Optionally register for unload.
    • Create WDFDRIVER.
    • Call ACX to do any post driver init.
    • Optionally do any post driver init.
  • WDF DeviceAdd. Device-scoped.

    • Call ACX to init the device init context.
    • Create device.
    • Call ACX to do any post device init.
    • Optionally do any post device init.
  • WDF PrepareHardware. Device-scoped.

    • Create and init hardware resources (for interrupts and threads, register them with ACX).
  • WDF Device D0 Entry callback. Device-scoped.

  • WDF Queues are restarted.

  • WDF DeviceSelfManagedIoInit. Device-scoped.

  • WDF DeviceSelfManagedIoRestart. Device-scoped.

    • Init after each power up from Dx.

Circuit dynamic creation (at any time)

  • Driver allocates a WDFDEVICE_INIT structure by calling WdfPdoInitAllocate. The driver is responsible for invoking the WdfDeviceInitFree if it encounters any failures before successfully creating a device.
  • Driver specifies any PnP/power callbacks it wants to receive.
  • Driver creates a device.
  • Driver instantiates the new device/circuit by calling AcxDeviceAddCircuitDevice.
  • WDF/PnP takes over and the simple enum/startup pattern described in the previous section takes place.

AcxFactoryCircuit

An ACX driver can also create AcxFactoryCircuit objects (circuit providers) during power up sequence using the AcxFactoryCircuitCreate function and the AcxDeviceAddFactoryCircuit function.

Because the ACX driver registered itself with ACX as circuit factory, the ACX framework uses the registered factory to ask the driver to create a new circuit.

AcxFactoryCircuitCreate(Device, &attributes, &factoryInit, &factory);

AcxDeviceAddFactoryCircuit(Device, factory);

ACX device rebalance

Rebalancing is done when system resource usage requires the operating system to rebalance resources between devices. For general information about rebalance, see Implement PnP Rebalance for PortCls Audio Drivers.

ACX supports device rebalance as follows:

  • In the power down WDF/ACX sequence, the driver releases all streaming resources (EvtAcxStreamPowerDown, EvtAcxStreamReleaseHardware), circuit resources (EvtAcxCircuitPowerDown, EvtAcxCircuitReleaseHardware) and device resources (EvtDeviceReleaseHardware).

  • All requests are pended, and handles are left open.

  • In the power up WDF/ACX sequence, the driver makes sure the new resources are compatible with the current ones, and it makes any allowed adjustments to its settings. If the resources are not compatible with the current device/circuit initialization, the driver must delete the current circuits and create new ones. See below more information.

  • In the power up sequence, WDF invokes its EvtDevicePrepareHardware and EvtDeviceD0 entry, and ACX invokes the corresponding EvtAcxCircuitPrepareHardware and EvtAcxCircuitPowerUp, and it moves all streams into its pre-existing states.

  • As soon as the queues move to power up/run state, the I/O flow again.

ACX doesn't allow remove (fails query-remove) or rebalance (fails query-stop) to take place if there are streams in active (RUN) state.

Drivers may also opt to always destroy and recreate audio devices on rebalance. This is the same scenario above when the device detects that the new settings are not compatible with the old ones. The deletion of the circuit must be done in EvtDevicePrepareHardware/EvtDeviceReleaseHardware callbacks, and the new circuit is re-created in EvtDevicePrepareHardware. The driver deletes a circuit by un-registering the circuit (using AcxDeviceRemoveCircuit).

User mode file handles

ACX doesn’t wait for the user mode file handles to be closed before re-creating new circuits. The lifetime of the files system handles is not tied to the lifetime of the hardware resources used by the device/circuits. It is the responsibility of clients to listen for interface arrival/removal and close and re-open file handles.

Old file handles are marked obsolete and ACX fails all the I/O requests associated with them.

See also

ACX audio class extensions overview

ACX reference documentation

PnP and Power Management Callback Sequences