summaryrefslogtreecommitdiff
path: root/audio/SoundWire/Samples/SdcaVad/SdcaVDsp/renderAudioEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/SoundWire/Samples/SdcaVad/SdcaVDsp/renderAudioEngine.cpp')
-rw-r--r--audio/SoundWire/Samples/SdcaVad/SdcaVDsp/renderAudioEngine.cpp502
1 files changed, 502 insertions, 0 deletions
diff --git a/audio/SoundWire/Samples/SdcaVad/SdcaVDsp/renderAudioEngine.cpp b/audio/SoundWire/Samples/SdcaVad/SdcaVDsp/renderAudioEngine.cpp
new file mode 100644
index 00000000..e9bb9496
--- /dev/null
+++ b/audio/SoundWire/Samples/SdcaVad/SdcaVDsp/renderAudioEngine.cpp
@@ -0,0 +1,502 @@
+/*++
+
+ 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:
+
+ renderaudioengine.cpp
+
+Abstract:
+
+ Render Audio Engine - callbacks for Audio Engine Node
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include <devguid.h>
+#include "stdunk.h"
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "offloadStreamEngine.h"
+#include "SimPeakMeter.h"
+
+#include "TestProperties.h"
+#include "AudioFormats.h"
+
+#ifndef __INTELLISENSE__
+#include "renderaudioengine.tmh"
+#endif
+
+// Sizes for min/max for audioengine buffers
+// Buffer duration is for both ping and pong buffers combined
+// so multiply it by 2
+#define MIN_AUDIOENGINE_BUFFER_DURATION_IN_MS (10 * 2)
+#define MAX_AUDIOENGINE_BUFFER_DURATION_IN_MS (2000 * 2)
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxAudioEngineRetrieveBufferSizeLimits(
+ ACXAUDIOENGINE,
+ ACXDATAFORMAT DataFormat,
+ PULONG MinBufferBytes,
+ PULONG MaxBufferBytes
+ )
+{
+ PAGED_CODE();
+
+ ULONG bytesPerSecond = AcxDataFormatGetAverageBytesPerSec(DataFormat);
+
+ *MinBufferBytes = (ULONG) (MIN_AUDIOENGINE_BUFFER_DURATION_IN_MS * bytesPerSecond / 1000);
+ *MaxBufferBytes = (ULONG) (MAX_AUDIOENGINE_BUFFER_DURATION_IN_MS * bytesPerSecond / 1000);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxAudioEngineRetrieveEffectsState(
+ ACXAUDIOENGINE AudioEngine,
+ PULONG State
+)
+{
+ PAGED_CODE();
+
+ PDSP_ENGINE_CONTEXT pAudioEngineCtx;
+ pAudioEngineCtx = GetDspEngineContext(AudioEngine);
+
+ *State = pAudioEngineCtx->GFxEnabled;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxAudioEngineAssignEffectsState(
+ ACXAUDIOENGINE AudioEngine,
+ ULONG State
+)
+{
+ PAGED_CODE();
+
+ PDSP_ENGINE_CONTEXT pAudioEngineCtx;
+ pAudioEngineCtx = GetDspEngineContext(AudioEngine);
+
+ pAudioEngineCtx->GFxEnabled = (BOOLEAN)State;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineRetrieveEffectsState(
+ ACXSTREAMAUDIOENGINE StreamAudioEngine,
+ PULONG State
+)
+{
+ PAGED_CODE();
+
+ PDSP_STREAMAUDIOENGINE_CONTEXT pStreamAudioEngineCtx;
+ pStreamAudioEngineCtx = GetDspStreamAudioEngineContext(StreamAudioEngine);
+
+ *State = pStreamAudioEngineCtx->LFxEnabled;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineAssignEffectsState(
+ ACXSTREAMAUDIOENGINE StreamAudioEngine,
+ ULONG State
+)
+{
+ PAGED_CODE();
+
+ PDSP_STREAMAUDIOENGINE_CONTEXT pStreamAudioEngineCtx;
+ pStreamAudioEngineCtx = GetDspStreamAudioEngineContext(StreamAudioEngine);
+
+ pStreamAudioEngineCtx->LFxEnabled = (BOOLEAN)State;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxAudioEngineRetrieveEngineMixFormat(
+ ACXAUDIOENGINE AudioEngine,
+ ACXDATAFORMAT * Format
+ )
+{
+ PDSP_ENGINE_CONTEXT audioEngineCtx;
+ PAGED_CODE();
+
+ audioEngineCtx = GetDspEngineContext(AudioEngine);
+
+ if (!audioEngineCtx->MixFormat)
+ {
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ *Format = audioEngineCtx->MixFormat;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxAudioEngineAssignEngineDeviceFormat(
+ _In_ ACXAUDIOENGINE AudioEngine,
+ _In_ ACXDATAFORMAT Format
+ )
+{
+ PAGED_CODE();
+
+ // Get the downstream pin
+ ACXCIRCUIT parentCircuit = (ACXCIRCUIT)AcxElementGetContainer((ACXELEMENT)AudioEngine);
+
+ ACXPIN downstreamPin = AcxCircuitGetPinById(parentCircuit, DspPinTypeBridge);
+ if (!downstreamPin)
+ {
+ RETURN_NTSTATUS(STATUS_INTERNAL_ERROR);
+ }
+
+ // Start by getting the list of formats for the raw mode
+ ACXDATAFORMATLIST formatList;
+ RETURN_NTSTATUS_IF_FAILED(AcxPinRetrieveModeDataFormatList(downstreamPin, &AUDIO_SIGNALPROCESSINGMODE_RAW, &formatList));
+
+ // Find the format we were given in that list.
+ NTSTATUS status = STATUS_NO_MATCH;
+
+ ACX_DATAFORMAT_LIST_ITERATOR formatListIter;
+ ACX_DATAFORMAT_LIST_ITERATOR_INIT(&formatListIter);
+ AcxDataFormatListBeginIteration(formatList, &formatListIter);
+
+ ACXDATAFORMAT listFormat;
+ while (NT_SUCCESS(AcxDataFormatListRetrieveNextFormat(formatList, &formatListIter, &listFormat)))
+ {
+ if (AcxDataFormatIsEqual(listFormat, Format))
+ {
+ // Assign the format as the default format.
+ // Note there is an existing ACX issue with default format assignment - assigning the default
+ // will only work if the format is already in the list (or is the first format added to the list).
+ AcxDataFormatListAssignDefaultDataFormat(formatList, listFormat);
+
+ // Use the format we pulled out of our list since it will have an appropriate lifetime
+ PDSP_ENGINE_CONTEXT audioEngineCtx;
+ audioEngineCtx = GetDspEngineContext(AudioEngine);
+ audioEngineCtx->MixFormat = listFormat;
+
+ status = STATUS_SUCCESS;
+
+ break;
+ }
+ }
+ AcxDataFormatListEndIteration(formatList, &formatListIter);
+
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtPeakMeterRetrieveLevelCallback(
+ ACXPEAKMETER PeakMeter,
+ ULONG Channel,
+ LONG * PeakMeterLevel
+ )
+{
+ PAGED_CODE();
+
+ ASSERT(PeakMeter);
+
+ if (Channel == ALL_CHANNELS_ID)
+ {
+ Channel = 0;
+ }
+
+ PDSP_PEAKMETER_ELEMENT_CONTEXT peakmeterCtx = GetDspPeakMeterElementContext(PeakMeter);
+ ASSERT(peakmeterCtx);
+ CSimPeakMeter* peakMeter = (CSimPeakMeter *)peakmeterCtx->peakMeter;
+ *PeakMeterLevel = peakMeter->GetValue(Channel);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtMuteAssignState(
+ ACXMUTE Mute,
+ ULONG Channel,
+ ULONG State
+ )
+{
+ PDSP_MUTE_ELEMENT_CONTEXT muteCtx;
+ ULONG i;
+
+ PAGED_CODE();
+
+ muteCtx = GetDspMuteElementContext(Mute);
+ ASSERT(muteCtx);
+
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ muteCtx->MuteState[Channel] = State;
+ }
+ else
+ {
+ for (i = 0; i < MAX_CHANNELS; ++i)
+ {
+ muteCtx->MuteState[i] = State;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtMuteRetrieveState(
+ ACXMUTE Mute,
+ ULONG Channel,
+ ULONG * State
+ )
+{
+ PDSP_MUTE_ELEMENT_CONTEXT muteCtx;
+
+ PAGED_CODE();
+
+ muteCtx = GetDspMuteElementContext(Mute);
+ ASSERT(muteCtx);
+
+ // use first channel for all channels setting.
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ *State = muteCtx->MuteState[Channel];
+ }
+ else
+ {
+ *State = muteCtx->MuteState[0];
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtRampedVolumeAssignLevel(
+ ACXVOLUME Volume,
+ ULONG Channel,
+ LONG VolumeLevel,
+ ACX_VOLUME_CURVE_TYPE,
+ ULONGLONG
+ )
+{
+ PDSP_VOLUME_ELEMENT_CONTEXT volumeCtx;
+ ULONG i;
+
+ PAGED_CODE();
+
+ volumeCtx = GetDspVolumeElementContext(Volume);
+ ASSERT(volumeCtx);
+
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ volumeCtx->VolumeLevel[Channel] = VolumeLevel;
+ }
+ else
+ {
+ for (i = 0; i < MAX_CHANNELS; ++i)
+ {
+ volumeCtx->VolumeLevel[i] = VolumeLevel;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtVolumeRetrieveLevel(
+ ACXVOLUME Volume,
+ ULONG Channel,
+ LONG * VolumeLevel
+)
+{
+ PDSP_VOLUME_ELEMENT_CONTEXT volumeCtx;
+
+ PAGED_CODE();
+
+ volumeCtx = GetDspVolumeElementContext(Volume);
+ ASSERT(volumeCtx);
+
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ *VolumeLevel = volumeCtx->VolumeLevel[Channel];
+ }
+ else
+ {
+ *VolumeLevel = volumeCtx->VolumeLevel[0];
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineRetrievePresentationPosition(
+ _In_ ACXSTREAMAUDIOENGINE StreamAudioEngine,
+ _Out_ PULONGLONG PositionInBlocks,
+ _Out_ PULONGLONG QPCPosition
+)
+{
+ NTSTATUS status = STATUS_INVALID_PARAMETER;
+ ACXSTREAM stream;
+ PDSP_STREAM_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ stream = AcxStreamAudioEngineGetStream(StreamAudioEngine);
+ if (stream)
+ {
+ ctx = GetDspStreamContext(stream);
+
+ streamEngine = static_cast<CStreamEngine*>(ctx->StreamEngine);
+
+ status = streamEngine->GetPresentationPosition(PositionInBlocks, QPCPosition);
+ }
+
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineAssignCurrentWritePosition(
+ _In_ ACXSTREAMAUDIOENGINE StreamAudioEngine,
+ _In_ ULONG Position
+)
+{
+ NTSTATUS status = STATUS_INVALID_PARAMETER;
+ ACXSTREAM stream;
+ PDSP_STREAM_CONTEXT ctx;
+ COffloadStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ stream = AcxStreamAudioEngineGetStream(StreamAudioEngine);
+ if (stream)
+ {
+ ctx = GetDspStreamContext(stream);
+
+ if (ctx->PinType == DspPinTypeOffload)
+ {
+ streamEngine = static_cast<COffloadStreamEngine*>(ctx->StreamEngine);
+
+ status = streamEngine->SetCurrentWritePosition(Position);
+ }
+ else
+ {
+ status = STATUS_NOT_SUPPORTED;
+ }
+ }
+
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineRetrieveLinearBufferPosition(
+ _In_ ACXSTREAMAUDIOENGINE StreamAudioEngine,
+ _Out_ PULONGLONG Position
+)
+{
+ NTSTATUS status = STATUS_INVALID_PARAMETER;
+ ACXSTREAM stream;
+ PDSP_STREAM_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ stream = AcxStreamAudioEngineGetStream(StreamAudioEngine);
+ if (stream)
+ {
+ ctx = GetDspStreamContext(stream);
+
+ streamEngine = static_cast<CStreamEngine*>(ctx->StreamEngine);
+
+ status = streamEngine->GetLinearBufferPosition(Position);
+ }
+
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineAssignLastBufferPosition(
+ _In_ ACXSTREAMAUDIOENGINE StreamAudioEngine,
+ _In_ ULONG Position
+)
+{
+ NTSTATUS status = STATUS_INVALID_PARAMETER;
+ ACXSTREAM stream;
+ PDSP_STREAM_CONTEXT ctx;
+ COffloadStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ stream = AcxStreamAudioEngineGetStream(StreamAudioEngine);
+ if (stream)
+ {
+ ctx = GetDspStreamContext(stream);
+
+ if (ctx->PinType == DspPinTypeOffload)
+ {
+ streamEngine = static_cast<COffloadStreamEngine*>(ctx->StreamEngine);
+
+ status = streamEngine->SetLastBufferPosition(Position);
+ }
+ else
+ {
+ status = STATUS_NOT_SUPPORTED;
+ }
+ }
+
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+DspR_EvtAcxStreamAudioEngineAssignLoopbackProtection(
+ _In_ ACXSTREAMAUDIOENGINE,
+ _In_ ACX_CONSTRICTOR_OPTION
+)
+{
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+