summaryrefslogtreecommitdiff
path: root/audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp
diff options
context:
space:
mode:
authorDaniel Rugerio <[email protected]>2025-11-25 11:00:04 -0800
committerDaniel Rugerio <[email protected]>2025-12-15 14:00:37 -0800
commit6fa87d3bef7972f7fac034adb68cd856f69c8607 (patch)
tree90ddf9e506b651c81dd803e0a9cc04af5db24a79 /audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp
parent1d89a1513f519f62226f84a3131916ab2fd0c3ef (diff)
New SDCAVAD sample.
Diffstat (limited to 'audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp')
-rw-r--r--audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp286
1 files changed, 286 insertions, 0 deletions
diff --git a/audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp b/audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp
new file mode 100644
index 00000000..e7b36b1f
--- /dev/null
+++ b/audio/SoundWire/Samples/SdcaVad/SdcaVCodec/CircuitHelper.cpp
@@ -0,0 +1,286 @@
+/*++
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ CircuitHelper.cpp
+
+Abstract:
+
+ This module contains helper functions for device.cpp and render.cpp files.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "CircuitHelper.h"
+
+#ifndef __INTELLISENSE__
+#include "CircuitHelper.tmh"
+#endif
+
+PAGED_CODE_SEG
+NTSTATUS CreateRenderCircuit(
+ _In_ PACXCIRCUIT_INIT CircuitInit,
+ _In_ UNICODE_STRING CircuitName,
+ _In_ WDFDEVICE Device,
+ _Out_ ACXCIRCUIT* Circuit
+)
+{
+
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_RENDER_CIRCUIT_CONTEXT);
+
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitInitAssignName(CircuitInit, &CircuitName));
+
+ //
+ // Add circuit type.
+ //
+ AcxCircuitInitSetCircuitType(CircuitInit, AcxCircuitTypeRender);
+
+ //
+ // Assign the circuit's pnp-power callbacks.
+ //
+ {
+ ACX_CIRCUIT_PNPPOWER_CALLBACKS powerCallbacks;
+ ACX_CIRCUIT_PNPPOWER_CALLBACKS_INIT(&powerCallbacks);
+ powerCallbacks.EvtAcxCircuitPowerUp = CodecR_EvtCircuitPowerUp;
+ powerCallbacks.EvtAcxCircuitPowerDown = CodecR_EvtCircuitPowerDown;
+ AcxCircuitInitSetAcxCircuitPnpPowerCallbacks(CircuitInit, &powerCallbacks);
+ }
+
+ //
+ // Assign the circuit's composite callbacks.
+ //
+ {
+ ACX_CIRCUIT_COMPOSITE_CALLBACKS compositeCallbacks;
+ ACX_CIRCUIT_COMPOSITE_CALLBACKS_INIT(&compositeCallbacks);
+ compositeCallbacks.EvtAcxCircuitCompositeCircuitInitialize = CodecR_EvtCircuitCompositeCircuitInitialize;
+ compositeCallbacks.EvtAcxCircuitCompositeInitialize = CodecR_EvtCircuitCompositeInitialize;
+ AcxCircuitInitSetAcxCircuitCompositeCallbacks(CircuitInit, &compositeCallbacks);
+ }
+
+ //
+ // Set circuit-callbacks.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitInitAssignAcxRequestPreprocessCallback(
+ CircuitInit,
+ CodecR_EvtCircuitRequestPreprocess,
+ (ACXCONTEXT)AcxRequestTypeAny, // dbg only
+ AcxRequestTypeAny,
+ NULL,
+ AcxItemIdNone));
+
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitInitAssignAcxCreateStreamCallback(
+ CircuitInit,
+ CodecR_EvtCircuitCreateStream));
+
+ //
+ // Create the circuit.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_RENDER_CIRCUIT_CONTEXT);
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitCreate(Device, &attributes, &CircuitInit, Circuit));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ConnectRenderCircuitElements(
+ _In_ ULONG ElementCount,
+ _In_reads_(ElementCount) ACXELEMENT* Elements,
+ _In_ ACXCIRCUIT Circuit
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // Explicitly connect the circuit/elements. Note that driver doens't
+ // need to perform this step when circuit/elements are connected in the
+ // same order as they were added to the circuit. By default ACX connects
+ // the elements starting from the sink circuit pin and ending with the
+ // source circuit pin for both render and capture devices.
+ //
+ // circuit.pin[default_sink] -> 1st element.pin[default_in]
+ // 1st element.pin[default_out] -> 2nd element.pin[default_in]
+ // 2nd element.pin[default_out] -> circuit.pin[default_source]
+ //
+ const int numElements = 2;
+ const int numConnections = numElements + 1;
+
+ ACX_CONNECTION connections[numConnections];
+ ACX_CONNECTION_INIT(&connections[0], Circuit, Elements[ElementCount - 2]);
+ ACX_CONNECTION_INIT(&connections[1], Elements[ElementCount - 2], Elements[ElementCount - 1]);
+ ACX_CONNECTION_INIT(&connections[2], Elements[ElementCount - 1], Circuit);
+
+ //
+ // Add the connections linking circuit to elements.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitAddConnections(Circuit, connections, SIZEOF_ARRAY(connections)));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ObjBagAddBlob(
+ _In_ ACXOBJECTBAG ObjBag,
+ _In_z_ const char* Blob
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DECLARE_CONST_ACXOBJECTBAG_SYSTEM_PROPERTY_NAME(VendorPropertiesBlock);
+ STRING vendorBlob;
+ RtlInitString(&vendorBlob, Blob);
+ WDFMEMORY vendorBlobMem;
+ RETURN_NTSTATUS_IF_FAILED(WdfMemoryCreatePreallocated(NULL, vendorBlob.Buffer, vendorBlob.MaximumLength, &vendorBlobMem));
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddBlob(ObjBag, &VendorPropertiesBlock, vendorBlobMem));
+ WdfObjectDelete(vendorBlobMem);
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ObjBagAddEndpointId(
+ _In_ ACXOBJECTBAG ObjBag,
+ _In_ UINT Value
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DECLARE_CONST_ACXOBJECTBAG_SOUNDWIRE_PROPERTY_NAME(EndpointId);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddUI4(ObjBag, &EndpointId, Value));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ObjBagAddDataPortNumber(
+ _In_ ACXOBJECTBAG ObjBag,
+ _In_ UINT Value
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DECLARE_CONST_ACXOBJECTBAG_SOUNDWIRE_PROPERTY_NAME(DataPortNumber);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddUI4(ObjBag, &DataPortNumber, Value));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ObjBagAddTestUI4(
+ _In_ ACXOBJECTBAG ObjBag,
+ _In_ UINT Value
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DECLARE_CONST_ACXOBJECTBAG_DRIVER_PROPERTY_NAME(msft, TestUI4);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddUI4(ObjBag, &TestUI4, Value));
+
+ return status;
+}
+
+
+PAGED_CODE_SEG
+NTSTATUS ObjBagAddCircuitId(
+ _In_ ACXOBJECTBAG ObjBag,
+ _In_ GUID Guid
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DECLARE_CONST_ACXOBJECTBAG_DRIVER_PROPERTY_NAME(msft, CircuitId);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddGuid(ObjBag, &CircuitId, Guid));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ObjBagAddUnicodeStrings(
+ _In_ ACXOBJECTBAG ObjBag,
+ _In_ UNICODE_STRING FriendlyNameStr,
+ _In_ UNICODE_STRING NameStr
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DECLARE_CONST_ACXOBJECTBAG_SYSTEM_PROPERTY_NAME(FriendlyName);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddUnicodeString(ObjBag, &FriendlyName, &FriendlyNameStr));
+
+ DECLARE_CONST_ACXOBJECTBAG_SYSTEM_PROPERTY_NAME(Name);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddUnicodeString(ObjBag, &Name, &NameStr));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS AddJack(
+ _In_ WDF_OBJECT_ATTRIBUTES Attributes,
+ _In_ ACXPIN Pin,
+ _In_ ULONG ChannelMapping,
+ _In_ ULONG Color,
+ _In_ ACX_JACK_CONNECTION_TYPE ConnectionType,
+ _In_ ACX_JACK_GEO_LOCATION GeoLocation,
+ _In_ ACX_JACK_GEN_LOCATION GenLocation,
+ _In_ ACX_JACK_PORT_CONNECTION PortConnection
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ ACX_JACK_CONFIG jackCfg;
+ ACX_JACK_CONFIG_INIT(&jackCfg);
+ jackCfg.Description.ChannelMapping = ChannelMapping;
+ jackCfg.Description.Color = Color;
+ jackCfg.Description.ConnectionType = ConnectionType;
+ jackCfg.Description.GeoLocation = GeoLocation;
+ jackCfg.Description.GenLocation = GenLocation;
+ jackCfg.Description.PortConnection = PortConnection;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&Attributes, CODEC_JACK_CONTEXT);
+ Attributes.ParentObject = Pin;
+
+ ACXJACK jack;
+ RETURN_NTSTATUS_IF_FAILED(AcxJackCreate(Pin, &Attributes, &jackCfg, &jack));
+
+ ASSERT(jack != NULL);
+
+ PCODEC_JACK_CONTEXT jackCtx;
+ jackCtx = GetCodecJackContext(jack);
+ ASSERT(jackCtx);
+ jackCtx->Dummy = 0;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxPinAddJacks(Pin, &jack, 1));
+
+ return status;
+}
+
+