📄 minwave.cpp
字号:
that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
that->requestedChannelCount = 6;
return STATUS_SUCCESS;
}
if ((*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_QUAD) || (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_SURROUND)) {
that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
that->requestedChannelCount = 4;
return STATUS_SUCCESS;
}
if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_STEREO) {
that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
that->requestedChannelCount = 2;
return STATUS_SUCCESS;
}
} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
PULONG AccessFlags = PULONG(PropertyRequest->Value);
*AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET;
PropertyRequest->ValueSize = sizeof(ULONG);
return STATUS_SUCCESS;
}
}
return STATUS_INVALID_PARAMETER;
}
///////////////////////////
NTSTATUS CreateMiniportWaveStreamCMI(CMiniportWaveStreamCMI **MiniportWaveStreamCMI, PUNKNOWN pUnknownOuter, POOL_TYPE PoolType)
{
PAGED_CODE();
DBGPRINT(("CreateMiniportWaveStreamCMI"));
#ifdef WAVERT
*MiniportWaveStreamCMI = new (PoolType, 'gnaa') CMiniportWaveStreamCMI(NULL);
#else
*MiniportWaveStreamCMI = new (PoolType, 'gnaa') CMiniportWaveStreamCMI(pUnknownOuter);
#endif
if (*MiniportWaveStreamCMI) {
(*MiniportWaveStreamCMI)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS CMiniportWaveStreamCMI::prepareStream()
{
PAGED_CODE();
DBGPRINT(("CMiniportWaveStreamCMI[%p]::prepareStream()", this));
DBGPRINT(("---streamIndex: %d, channelNumber: %d", streamIndex, channelNumber));
NTSTATUS ntStatus;
UInt8 reg;
UInt32 val;
if (state == KSSTATE_RUN) {
return STATUS_INVALID_DEVICE_REQUEST;
}
if (!(Miniport->cm)) {
DBGPRINT(("Miniport not set"));
return STATUS_INVALID_DEVICE_REQUEST;
}
enableSPDIF = ((currentSampleRate == 44100 || currentSampleRate == 48000 || currentSampleRate == 88200 || currentSampleRate == 96000) &&
((currentResolution == 16) || (currentResolution == 24)) && (currentChannelCount == 2)) &&
(Miniport->cm->enableSPDIFOut);
ntStatus = setupSPDIFPlayback(enableSPDIF);
if (!NT_SUCCESS(ntStatus)) {
return ntStatus;
}
if (!isCaptureStream) {
ntStatus = setDACChannels();
if (!NT_SUCCESS(ntStatus)) {
return ntStatus;
}
}
KeWaitForSingleObject(&Miniport->mutex, Executive, KernelMode, false, NULL);
val = channelNumber ? ADC_CH1 : ADC_CH0;
if (isCaptureStream) {
Miniport->cm->regFUNCTRL0 |= val; // 1->Recording
} else {
Miniport->cm->regFUNCTRL0 &= ~val; // 0->Playback
}
Miniport->CMIAdapter->writeUInt32(REG_FUNCTRL0, Miniport->cm->regFUNCTRL0);
//set sampling frequency
val = Miniport->CMIAdapter->readUInt32(REG_FUNCTRL1);
if ((currentSampleRate == 88200) || (currentSampleRate == 44100)) {
if (channelNumber) {
val &= ~SFC_CH1_MASK;
val |= SFC_44K_CH1;
} else {
val &= ~SFC_CH0_MASK;
val |= SFC_44K_CH0;
}
} else if ((currentSampleRate == 96000) || (currentSampleRate == 48000)) {
if (channelNumber) {
val &= ~SFC_CH1_MASK;
val |= SFC_48K_CH1;
} else {
val &= ~SFC_CH0_MASK;
val |= SFC_48K_CH0;
}
} else {
KeReleaseMutex(&Miniport->mutex, FALSE);
return STATUS_INVALID_DEVICE_REQUEST;
}
Miniport->CMIAdapter->writeUInt32(REG_FUNCTRL1, val);
//set resolution
val = Miniport->CMIAdapter->readUInt32(REG_CHFORMAT);
if (channelNumber) {
val |= FORMAT_CH1;
} else {
val |= FORMAT_CH0;
}
Miniport->CMIAdapter->writeUInt32(REG_CHFORMAT, val);
KeReleaseMutex(&Miniport->mutex, false);
return STATUS_SUCCESS;
}
NTSTATUS CMiniportWaveStreamCMI::setDACChannels()
{
PAGED_CODE();
DBGPRINT(("CMiniportWaveStreamCMI[%p]::setDACChannels()", this));
NTSTATUS ntStatus = STATUS_SUCCESS;
if (currentChannelCount > 2) {
if (Miniport->cm->maxChannels < currentChannelCount) {
return STATUS_INVALID_DEVICE_REQUEST;
}
if ((currentResolution != 16) || (currentChannelCount < 2)) {
return STATUS_INVALID_DEVICE_REQUEST;
}
#if OUT_CHANNEL == 0
return STATUS_INVALID_DEVICE_REQUEST;
#endif
KeWaitForSingleObject(&Miniport->mutex, Executive, KernelMode, FALSE, NULL);
Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, DWORD_MAPPING);
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, XCHG_DAC);
switch (currentChannelCount) {
case 4:
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_4CH_CH1);
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_5CH_CH1);
Miniport->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_6CH_CH1);
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_CENTER);
break;
case 6:
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_4CH_CH1);
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_5CH_CH1);
Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_6CH_CH1);
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_CENTER);
break;
case 8:
if (Miniport->cm->chipVersion == 68) {
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_4CH_CH1);
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_5CH_CH1);
Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_6CH_CH1);
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_CENTER);
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL2, EN_8CH_CH1);
break;
} else {
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
}
default:
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
}
KeReleaseMutex(&Miniport->mutex, FALSE);
} else {
if (Miniport->cm->canMultiChannel) {
KeWaitForSingleObject(&Miniport->mutex, Executive, KernelMode, FALSE, NULL);
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_5CH_CH1 | EN_4CH_CH1);
Miniport->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_6CH_CH1 | DWORD_MAPPING);
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_CENTER);
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, XCHG_DAC);
if (Miniport->cm->chipVersion == 68) {
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL2, EN_8CH_CH1);
}
KeReleaseMutex(&Miniport->mutex, FALSE);
}
}
return ntStatus;
}
NTSTATUS CMiniportWaveStreamCMI::setupSPDIFPlayback(bool enableSPDIF)
{
PAGED_CODE();
DBGPRINT(("CMiniportWaveStreamCMI[%p]::setupSPDIFPlayback(%d)", this, enableSPDIF));
NTSTATUS ntStatus;
KeWaitForSingleObject(&Miniport->mutex, Executive, KernelMode, false, NULL);
if (enableSPDIF) {
Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_SPDIF_OUT);
Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDO2DAC);
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDF_0);
#else
Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDF_1);
#endif
setupAC3Passthru();
if ( (currentSampleRate == 48000) || (currentSampleRate == 96000) ) {
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDIF_48);
} else {
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDIF_48);
}
if (currentSampleRate == 96000) {
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH0);
#else
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH1);
#endif
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, DBLSPDS);
} else if (currentSampleRate == 88200) {
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD88_CH0);
#else
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD88_CH1);
#endif
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, DBLSPDS);
} else {
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH0 | SPD96_CH0);
#else
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH1 | SPD96_CH1);
#endif
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, DBLSPDS);
}
} else {
Miniport->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_SPDIF_OUT);
Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDO2DAC);
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_0);
#else
Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_1);
#endif
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH0 | SPD96_CH0);
#else
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH1 | SPD96_CH1);
#endif
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, DBLSPDS);
setupAC3Passthru();
}
KeReleaseMutex(&Miniport->mutex, false);
return STATUS_SUCCESS;
}
NTSTATUS CMiniportWaveStreamCMI::setupAC3Passthru()
{
PAGED_CODE();
DBGPRINT(("CMiniportWaveStreamCMI[%p]::setupAC3Passthru()"));
if (enableAC3Passthru) {
Miniport->CMIAdapter->writeUInt8(REG_MIXER1, Miniport->CMIAdapter->readUInt8(REG_MIXER1) | MUTE_WAVE);
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_1);
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDO_AC3_2);
if (Miniport->cm->canAC3HW) {
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_3);
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SPD32SEL);
if (Miniport->cm->chipVersion >= 39) {
Miniport->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
}
} else {
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SPD32SEL);
if (Miniport->cm->chipVersion == 33) {
if (currentSampleRate >= 48000) {
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH0);
#else
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH1);
#endif
} else {
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH0);
#else
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH1);
#endif
}
}
}
} else {
Miniport->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_1);
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDO_AC3_2);
if (Miniport->cm->canAC3HW) {
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_3);
if (currentResolution > 16) {
Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SPD32SEL);
Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD24SEL);
} else {
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SPD32SEL);
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD24SEL);
}
} else {
Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SPD32SEL);
#if OUT_CHANNEL == 0
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH0);
#else
Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH1);
#endif
}
}
return STATUS_SUCCESS;
}
CMiniportWaveStreamCMI::~CMiniportWaveStreamCMI(void)
{
PAGED_CODE();
DBGPRINT(("CMiniportWaveStreamCMI[%p]::~CMiniportWaveStreamCMI", this));
#ifdef WAVERT
if (Port) {
Port->Release();
Port = NULL;
}
#else
if (DMAChannel) {
DMAChannel->Release();
DMAChannel = NULL;
}
if (ServiceGroup) {
ServiceGroup->Release();
ServiceGroup = NULL;
}
#endif
Miniport->isStreamRunning[streamIndex] = false;
if ((streamIndex == AC3_OUT_STREAM) && Miniport->isStreamRunning[PCM_OUT_STREAM]) {
KSSTATE temp = Miniport->stream[PCM_OUT_STREAM]->state;
Miniport->stream[PCM_OUT_STREAM]->state = KSSTATE_STOP;
Miniport->stream[PCM_OUT_STREAM]->prepareStream();
Miniport->stream[PCM_OUT_STREAM]->SetState(KSSTATE_ACQUIRE);
Miniport->stream[PCM_OUT_STREAM]->state = temp;
Miniport->stream[PCM_OUT_STREAM]->SetState(KSSTATE_RUN_AC3);
}
if (Miniport) {
Miniport->Release();
Miniport = NULL;
}
}
STDMETHODIMP CMiniportWaveStreamCMI::NonDelegatingQueryInterface(REFIID Interface, PVOID *Object)
{
PAGED_CODE();
ASSERT(Object);
DBGPRINT(("CMiniportWaveStreamCMI[%p]::NonDelegatingQueryInterface(%p, %p)", this, Interface, Object));
if (IsEqualGUIDAligned(Interface,IID_IUnknown)) {
*Object = PVOID(PUNKNOWN(PMINIPORTWAVECYCLICSTREAM(this)));
#ifdef WAVERT
} else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveRTStream)) {
*Object = PVOID(PMINIPORTWAVERTSTREAM(this));
#else
} else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveCyclicStream)) {
*Object = PVOID(PMINIPORTWAVECYCLICSTREAM(this));
#endif
} else if (IsEqualGUIDAligned (Interface, IID_IDrmAudioStream)) {
*Object = (PVOID)(PDRMAUDIOSTREAM(this));
} else {
*Object = NULL;
}
if (*Object) {
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
#ifdef WAVERT
NTSTATUS CMiniportWaveStreamCMI::Init(CMiniportWaveCMI* Miniport_, UInt32 streamIndex_, bool isCaptureStream_, PKSDATAFORMAT DataFormat, PPORTWAVERTSTREAM Port_)
#else
NTSTATUS CMiniportWaveStreamCMI::Init(CMiniportWaveCMI* Miniport_, UInt32 streamIndex_, bool isCaptureStream_, PKSDATAFORMAT DataFormat, PDMACHANNEL DMAChannel_, PSERVICEGROUP* OutServiceGroup)
#endif
{
PAGED_CODE();
ASSERT(Miniport_);
ASSERT(DataFormat);
NTSTATUS ntStatus;
#ifdef WAVERT
ASSERT(Port_);
DBGPRINT(("CMiniportWaveStreamCMI[%p]::Init(%p, %d, %d, %p, %p)", this, Miniport_, streamIndex_, isCaptureStream_, DataFormat, Port_));
Port = Port_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -