⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minwave.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        _DbgPrintF(DEBUGLVL_VERBOSE,("returning default format intersection") );
            
        RtlCopyMemory(ResultantFormat, ClientDataRange, sizeof( KSDATAFORMAT ) );
        *ResultantFormatLength = sizeof( KSDATAFORMAT );
    }
    
    return STATUS_SUCCESS;
}

/*****************************************************************************
 * CMiniportWaveCyclicSB16::NewStream()
 *****************************************************************************
 * Creates a new stream.  This function is called when a streaming pin is
 * created.
 */
STDMETHODIMP
CMiniportWaveCyclicSB16::
NewStream
(
    OUT     PMINIPORTWAVECYCLICSTREAM * OutStream,
    IN      PUNKNOWN                    OuterUnknown,
    IN      POOL_TYPE                   PoolType,
    IN      ULONG                       Channel,
    IN      BOOLEAN                     Capture,
    IN      PKSDATAFORMAT               DataFormat,
    OUT     PDMACHANNEL *               OutDmaChannel,
    OUT     PSERVICEGROUP *             OutServiceGroup
)
{
    PAGED_CODE();

    ASSERT(OutStream);
    ASSERT(DataFormat);
    ASSERT(OutDmaChannel);
    ASSERT(OutServiceGroup);

    _DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportWaveCyclicSB16::NewStream]"));

    NTSTATUS ntStatus = STATUS_SUCCESS;

    //
    // Make sure the hardware is not already in use.
    //
    if (Capture)
    {
        if (AllocatedCapture)
        {
            ntStatus = STATUS_INVALID_DEVICE_REQUEST;
        }
    }
    else
    {
        if (AllocatedRender)
        {
            ntStatus = STATUS_INVALID_DEVICE_REQUEST;
        }
    }

    //
    // Determine if the format is valid.
    //
    if (NT_SUCCESS(ntStatus))
    {
        ntStatus = ValidateFormat(DataFormat);
    }

    if(NT_SUCCESS(ntStatus))
    {
        // if we're trying to start a full-duplex stream.
        if(AllocatedCapture || AllocatedRender)
        {
            // make sure the requested sampling rate is the
            // same as the currently running one...
            PWAVEFORMATEX waveFormat = PWAVEFORMATEX(DataFormat + 1);
            if( SamplingFrequency != waveFormat->nSamplesPerSec )
            {
                // Bad format....
                ntStatus = STATUS_INVALID_PARAMETER;
            }
        }
    }

    PDMACHANNELSLAVE    dmaChannel = NULL;
    PWAVEFORMATEX       waveFormat = PWAVEFORMATEX(DataFormat + 1);

    //
    // Get the required DMA channel if it's not already in use.
    //
    if (NT_SUCCESS(ntStatus))
    {
        if (waveFormat->wBitsPerSample == 8)
        {
            if (! Allocated8Bit)
            {
                dmaChannel = DmaChannel8;
            }
        }
        else
        {
            if (! Allocated16Bit)
            {
                dmaChannel = DmaChannel16;
            }
        }
    }

    if (! dmaChannel)
    {
        ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    }
    else
    {
        //
        // Instantiate a stream.
        //
        CMiniportWaveCyclicStreamSB16 *stream =
            new(PoolType) CMiniportWaveCyclicStreamSB16(OuterUnknown);

        if (stream)
        {
            stream->AddRef();

            ntStatus =
                stream->Init
                (
                    this,
                    Channel,
                    Capture,
                    DataFormat,
                    dmaChannel
                );

            if (NT_SUCCESS(ntStatus))
            {
                if (Capture)
                {
                    AllocatedCapture = TRUE;
                }
                else
                {
                    AllocatedRender = TRUE;
                }

                if (waveFormat->wBitsPerSample == 8)
                {
                    Allocated8Bit = TRUE;
                }
                else
                {
                    Allocated16Bit = TRUE;
                }

                *OutStream = PMINIPORTWAVECYCLICSTREAM(stream);
                stream->AddRef();

#if OVERRIDE_DMA_CHANNEL
                *OutDmaChannel = PDMACHANNEL(stream);
                stream->AddRef();
#else // OVERRIDE_DMA_CHANNEL
                *OutDmaChannel = dmaChannel;
                dmaChannel->AddRef();
#endif // OVERRIDE_DMA_CHANNEL

                *OutServiceGroup = ServiceGroup;
                ServiceGroup->AddRef();

                //
                // The stream, the DMA channel, and the service group have
                // references now for the caller.  The caller expects these
                // references to be there.
                //
            }

            //
            // This is our private reference to the stream.  The caller has
            // its own, so we can release in any case.
            //
            stream->Release();
        }
        else
        {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    return ntStatus;
}

/*****************************************************************************
 * CMiniportWaveCyclic::RestoreSampleRate()
 *****************************************************************************
 * Restores the sample rate.
 */
STDMETHODIMP_(void) CMiniportWaveCyclicSB16::RestoreSampleRate (void)
{
    if (AllocatedCapture)
    {
        _DbgPrintF(DEBUGLVL_VERBOSE, ("Restoring Capture Sample Rate"));
        AdapterCommon->WriteController(DSP_CMD_SETADCRATE);
        AdapterCommon->WriteController((BYTE)(SamplingFrequency >> 8));
        AdapterCommon->WriteController((BYTE) SamplingFrequency);
    }
    if (AllocatedRender)
    {
        _DbgPrintF(DEBUGLVL_VERBOSE, ("Restoring Render Sample Rate"));
        AdapterCommon->WriteController(DSP_CMD_SETDACRATE);
        AdapterCommon->WriteController((BYTE)(SamplingFrequency >> 8));
        AdapterCommon->WriteController((BYTE) SamplingFrequency);
    }
}

/*****************************************************************************
 * CMiniportWaveCyclicStreamSB16::NonDelegatingQueryInterface()
 *****************************************************************************
 * Obtains an interface.  This function works just like a COM QueryInterface
 * call and is used if the object is not being aggregated.
 */
STDMETHODIMP
CMiniportWaveCyclicStreamSB16::
NonDelegatingQueryInterface
(
    IN      REFIID  Interface,
    OUT     PVOID * Object
)
{
    PAGED_CODE();

    ASSERT(Object);

    _DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportWaveCyclicStreamSB16::NonDelegatingQueryInterface]"));

    if (IsEqualGUIDAligned(Interface,IID_IUnknown))
    {
        *Object = PVOID(PUNKNOWN(PMINIPORTWAVECYCLICSTREAM(this)));
    }
    else
    if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveCyclicStream))
    {
        *Object = PVOID(PMINIPORTWAVECYCLICSTREAM(this));
    }
    else 
    if (IsEqualGUIDAligned (Interface, IID_IDrmAudioStream))
    {
        *Object = (PVOID)(PDRMAUDIOSTREAM(this));
    }
#if OVERRIDE_DMA_CHANNEL
    else 
    if (IsEqualGUIDAligned (Interface, IID_IDmaChannel))
    {
        *Object = (PVOID)(PDMACHANNEL(this));
    }
#endif // OVERRIDE_DMA_CHANNEL
    else
    {
        *Object = NULL;
    }

    if (*Object)
    {
        PUNKNOWN(*Object)->AddRef();
        return STATUS_SUCCESS;
    }

    return STATUS_INVALID_PARAMETER;
}

/*****************************************************************************
 * CMiniportWaveCyclicStreamSB16::~CMiniportWaveCyclicStreamSB16()
 *****************************************************************************
 * Destructor.
 */
CMiniportWaveCyclicStreamSB16::
~CMiniportWaveCyclicStreamSB16
(   void
)
{
    PAGED_CODE();

    _DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportWaveCyclicStreamSB16::~CMiniportWaveCyclicStreamSB16]"));

    if (DmaChannel)
    {
        DmaChannel->Release();
    }

    if (Miniport)
    {
        //
        // Clear allocation flags in the miniport.
        //
        if (Capture)
        {
            Miniport->AllocatedCapture = FALSE;
        }
        else
        {
            Miniport->AllocatedRender = FALSE;
        }

        if (Format16Bit)
        {
            Miniport->Allocated16Bit = FALSE;
        }
        else
        {
            Miniport->Allocated8Bit = FALSE;
        }

        Miniport->AdapterCommon->SaveMixerSettingsToRegistry();
        Miniport->Release();
    }
}

/*****************************************************************************
 * CMiniportWaveCyclicStreamSB16::Init()
 *****************************************************************************
 * Initializes a stream.
 */
NTSTATUS
CMiniportWaveCyclicStreamSB16::
Init
(
    IN      CMiniportWaveCyclicSB16 *   Miniport_,
    IN      ULONG                       Channel_,
    IN      BOOLEAN                     Capture_,
    IN      PKSDATAFORMAT               DataFormat,
    IN      PDMACHANNELSLAVE            DmaChannel_
)
{
    PAGED_CODE();

    _DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportWaveCyclicStreamSB16::Init]"));

    ASSERT(Miniport_);
    ASSERT(DataFormat);
    ASSERT(NT_SUCCESS(Miniport_->ValidateFormat(DataFormat)));
    ASSERT(DmaChannel_);

    PWAVEFORMATEX waveFormat = PWAVEFORMATEX(DataFormat + 1);

    //
    // We must add references because the caller will not do it for us.
    //
    Miniport = Miniport_;
    Miniport->AddRef();

    DmaChannel = DmaChannel_;
    DmaChannel->AddRef();

    Channel         = Channel_;
    Capture         = Capture_;
    FormatStereo    = (waveFormat->nChannels == 2);
    Format16Bit     = (waveFormat->wBitsPerSample == 16);
    State           = KSSTATE_STOP;

    RestoreInputMixer = FALSE;

    KeWaitForSingleObject
    (
        &Miniport->SampleRateSync,
        Executive,
        KernelMode,
        FALSE,
        NULL
    );
    Miniport->SamplingFrequency = waveFormat->nSamplesPerSec;
    KeReleaseMutex(&Miniport->SampleRateSync,FALSE);
    
    return SetFormat( DataFormat );
}

/*****************************************************************************
 * CMiniportWaveCyclicStreamSB16::SetNotificationFreq()
 *****************************************************************************
 * Sets the notification frequency.
 */
STDMETHODIMP_(ULONG)
CMiniportWaveCyclicStreamSB16::
SetNotificationFreq
(
    IN      ULONG   Interval,
    OUT     PULONG  FramingSize    
)
{
    PAGED_CODE();

    _DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportWaveCyclicStreamSB16::SetNotificationFreq]"));

    Miniport->NotificationInterval = Interval;
    //
    //  This value needs to be sample block aligned for DMA to work correctly.
    //
    *FramingSize = 
        (1 << (FormatStereo + Format16Bit)) * 
            (Miniport->SamplingFrequency * Interval / 1000);

    return Miniport->NotificationInterval;
}

/*****************************************************************************
 * CMiniportWaveCyclicStreamSB16::SetFormat()
 *****************************************************************************
 * Sets the wave format.
 */
STDMETHODIMP
CMiniportWaveCyclicStreamSB16::
SetFormat
(
    IN      PKSDATAFORMAT   Format
)
{
    PAGED_CODE();

    ASSERT(Format);

    _DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportWaveCyclicStreamSB16::SetFormat]"));

    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

    if(State != KSSTATE_RUN)
    {
        ntStatus = Miniport->ValidateFormat(Format);
    
        PWAVEFORMATEX waveFormat = PWAVEFORMATEX(Format + 1);

        KeWaitForSingleObject
        (
            &Miniport->SampleRateSync,
            Executive,
            KernelMode,
            FALSE,
            NULL
        );
    
        // check for full-duplex stuff
        if( NT_SUCCESS(ntStatus)
            && Miniport->AllocatedCapture
            && Miniport->AllocatedRender
        )
        {
            // no new formats.... bad...
            if( Miniport->SamplingFrequency != waveFormat->nSamplesPerSec )
            {
                // Bad format....
                ntStatus = STATUS_INVALID_PARAMETER;
            }
        }
    
        // TODO:  Validate sample size.
    
        if (NT_SUCCESS(ntStatus))
        {
            Miniport->SamplingFrequency = waveFormat->nSamplesPerSec;
    
            BYTE command =
                (   Capture
                ?   DSP_CMD_SETADCRATE
                :   DSP_CMD_SETDACRATE
                );
    
            Miniport->AdapterCommon->WriteController
            (
                command
            );
    
            Miniport->AdapterCommon->WriteController
            (
                (BYTE)(waveFormat->nSamplesPerSec >> 8)
            );
    
            Miniport->AdapterCommon->WriteController
            (
                (BYTE) waveFormat->nSamplesPerSec
            );

            _DbgPrintF(DEBUGLVL_VERBOSE,("  SampleRate: %d",waveFormat->nSamplesPerSec));
        }

        KeReleaseMutex(&Miniport->SampleRateSync,FALSE);
    }

    return ntStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -