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

📄 hwctxt.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                case D0:
                    if (m_Dx != D0)
                    {
                        m_Dx = D0;

                        PowerUp();

                        Lock();

                        if (m_bSavedOutputDMARunning)
                        {
                            m_bSavedOutputDMARunning = FALSE;
                            SetInterruptEvent(m_dwSysintrOutput);
                            //StartOutputDMA();
                        }

                        Unlock();
                    }
                    break;
                default:
                    if (m_Dx != (_CEDEVICE_POWER_STATE)D4)
                    {
                        // Save last DMA state before Power Down
                        m_bSavedInputDMARunning = m_bInputDMARunning;
                        m_bSavedOutputDMARunning = m_bOutputDMARunning;

                        m_Dx = (_CEDEVICE_POWER_STATE)D4;

                        Lock();

                        StopOutputDMA();
                        StopInputDMA();

                        Unlock();

                        PowerDown();
                    }
                    break;
                }

                // return our state
                *(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;

                *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);

                WAV_INF((_T("[WAV:INF] IOCTL_POWER_SET -> [D%d]\n\r"), m_Dx));
            }
            else
            {
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                WAV_ERR((_T("[WAV:ERR] CEDEVICE_POWER_STATE : Invalid Parameter Dx\n\r")));
            }
        }
        break;

    case IOCTL_POWER_GET:
        if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
        {
            bRc = FALSE;
            dwErr = ERROR_INVALID_PARAMETER;
            break;
        }

        *(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;

        WAV_INF((_T("WAVEDEV: IOCTL_POWER_GET: D%u \r\n"), m_Dx));

        *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
        break;

    default:
        bRc = FALSE;
        dwErr = ERROR_INVALID_FUNCTION;
        WAV_INF((_T(" Unsupported ioctl 0x%X\r\n"), dwCode));
        break;
    }

    if (!bRc)
    {
        SetLastError(dwErr);
    }

    return(bRc);
}


BOOL
HardwareContext::StartOutputDMA()
{
    ULONG OutputTransferred;

    WAV_MSG((_T("[WAV] StartOutputDMA()\r\n")));

    if((m_bOutputDMARunning == FALSE) && (m_Dx == D0))
    {
        m_bOutputDMARunning = TRUE;
        m_nOutByte[OUTPUT_DMA_BUFFER0] = 0;
        m_nOutByte[OUTPUT_DMA_BUFFER1] = 0;

        m_nOutputBufferInUse = OUTPUT_DMA_BUFFER0;    // Start DMA with Buffer 0
        m_OutputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
        OutputTransferred = TransferOutputBuffer(m_OutputDMAStatus);

        if(OutputTransferred)
        {
            CodecPowerControl();                    // Turn Output Channel
            CodecMuteControl(DMA_CH_OUT, FALSE);    // Unmute Output Channel

            // AC97 PCM output enable
            AC97_set_pcmout_transfer_mode(AC97_CH_DMA);

            // Output DMA Start
            DMA_set_channel_source(&g_OutputDMA, m_OutputDMABufferPhyPage[OUTPUT_DMA_BUFFER0], WORD_UNIT, BURST_1, INCREASE);
            DMA_set_channel_destination(&g_OutputDMA, AC97_get_pcmout_physical_buffer_address(), WORD_UNIT, BURST_1, FIXED);
            DMA_set_channel_transfer_size(&g_OutputDMA, AUDIO_DMA_PAGE_SIZE);
            DMA_set_initial_LLI(&g_OutputDMA, 1);
            DMA_channel_start(&g_OutputDMA);
        }
        else
        {
            WAV_ERR((_T("[WAV:ERR] StartOutputDMA() : There is no data to transfer\r\n")));
            m_bOutputDMARunning = FALSE;
        }
    }
    else
    {
        WAV_ERR((_T("[WAV:ERR] StartOutputDMA() : Output DMA is already running or m_Dx[%d] is not D0\r\n"), m_Dx));
        return FALSE;
    }

    return TRUE;
}


void
HardwareContext::StopOutputDMA()
{
    WAV_MSG((_T("[WAV] StopOutputDMA()\r\n")));

    if (m_bOutputDMARunning)
    {
        m_OutputDMAStatus = DMA_CLEAR;

        // Stop output DMA
        DMA_channel_stop(&g_OutputDMA);

        // AC97 PCM output disable
        AC97_set_pcmout_transfer_mode(AC97_CH_OFF);
    }

    m_bOutputDMARunning = FALSE;

    CodecMuteControl(DMA_CH_OUT, TRUE);
    CodecPowerControl();
}


BOOL
HardwareContext::StartInputDMA()
{
    WAV_MSG((_T("[WAV] StartInputDMA()\r\n")));

    if(m_bInputDMARunning == FALSE)
    {
        m_bInputDMARunning = TRUE;

        m_nInByte[INPUT_DMA_BUFFER0] = 0;
        m_nInByte[INPUT_DMA_BUFFER1] = 0;

        m_nInputBufferInUse = INPUT_DMA_BUFFER0;    // Start DMA with Buffer 0
        m_InputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;

        CodecPowerControl();                    // Turn On Channel
        CodecMuteControl(DMA_CH_IN, FALSE);    // Unmute Input Channel

        // AC97 PCM input enable
        AC97_set_pcmin_transfer_mode(AC97_CH_DMA);

        DMA_set_channel_source(&g_InputDMA, AC97_get_pcmin_physical_buffer_address(), WORD_UNIT, BURST_1, FIXED);
        DMA_set_channel_destination(&g_InputDMA, m_InputDMABufferPhyPage[INPUT_DMA_BUFFER0], WORD_UNIT, BURST_1, INCREASE);
        DMA_set_channel_transfer_size(&g_InputDMA, AUDIO_DMA_PAGE_SIZE);
        DMA_set_initial_LLI(&g_InputDMA, 1);
        DMA_channel_start(&g_InputDMA);
    }
    else
    {
        WAV_ERR((_T("[WAV:ERR] StartInputDMA() : Input DMA is already running\r\n")));
        return FALSE;
    }

    return TRUE;
}


void
HardwareContext::StopInputDMA()
{
    WAV_MSG((_T("[WAV] StopInputDMA()\r\n")));

    if (m_bInputDMARunning)
    {
        DMA_channel_stop(&g_InputDMA);
        AC97_set_pcmin_transfer_mode(AC97_CH_OFF);

        m_InputDMAStatus = DMA_CLEAR;
    }

    m_bInputDMARunning = FALSE;

    CodecMuteControl(DMA_CH_IN, TRUE);
    CodecPowerControl();
}


DWORD
HardwareContext::GetOutputGain (void)
{
    return m_dwOutputGain;
}


MMRESULT
HardwareContext::SetOutputGain (DWORD dwGain)
{
    WAV_MSG((_T("[WAV] SetOutputGain(0x%08x)\r\n"), dwGain));

    m_dwOutputGain = dwGain & 0xffff;    // save off so we can return this from GetGain - but only MONO

    // convert 16-bit gain to 5-bit attenuation
    UCHAR ucGain;
    if (m_dwOutputGain == 0)
    {
        ucGain = 0x3F; // mute: set maximum attenuation
    }
    else
    {
        ucGain = (UCHAR) ((0xffff - m_dwOutputGain) >> 11);    // codec supports 64dB attenuation, we'll only use 32
    }

    //ASSERT((ucGain & 0xC0) == 0); // bits 6,7 clear indicate DATA0 in Volume mode.

    return MMSYSERR_NOERROR;
}


DWORD
HardwareContext::GetInputGain (void)
{
    return m_dwInputGain;
}


MMRESULT
HardwareContext::SetInputGain (DWORD dwGain)
{
    WAV_MSG((_T("[WAV] SetInputGain(0x%08x)\r\n"), dwGain));

    m_dwInputGain = dwGain;

    if (!m_bInputMute)
    {
        m_InputDeviceContext.SetGain(dwGain);
    }

    return MMSYSERR_NOERROR;
}


BOOL
HardwareContext::GetOutputMute (void)
{
    return m_bOutputMute;
}


MMRESULT
HardwareContext::SetOutputMute (BOOL bMute)
{
    USHORT CodecReg;

    m_bOutputMute = bMute;

    CodecReg = ReadCodecRegister(WM9713_HEADPHONE_VOL);

    if (bMute)
    {
        CodecReg |= 0x8080;
    }
    else
    {
        CodecReg &= ~0x8080;
    }

    WriteCodecRegister(WM9713_HEADPHONE_VOL, CodecReg);

    return MMSYSERR_NOERROR;
}


BOOL
HardwareContext::GetInputMute (void)
{
    return m_bInputMute;
}


MMRESULT
HardwareContext::SetInputMute (BOOL bMute)
{
    m_bInputMute = bMute;
    return m_InputDeviceContext.SetGain(bMute ? 0: m_dwInputGain);
}


DWORD
HardwareContext::ForceSpeaker(BOOL bForceSpeaker)
{
    // If m_NumForcedSpeaker is non-zero, audio should be routed to an
    // external speaker (if hw permits).
    if (bForceSpeaker)
    {
        m_NumForcedSpeaker++;
        if (m_NumForcedSpeaker == 1)
        {
            SetSpeakerEnable(TRUE);
        }
    }
    else
    {
        m_NumForcedSpeaker--;
        if (m_NumForcedSpeaker ==0)
        {
            SetSpeakerEnable(FALSE);
        }
    }

    return MMSYSERR_NOERROR;
}


void
HardwareContext::InterruptThreadOutputDMA()
{
    ULONG OutputTransferred;

#if (_WIN32_WCE < 600)
    // Fast way to access embedded pointers in wave headers in other processes.
    SetProcPermissions((DWORD)-1);
#endif

    WAV_INF((_T("[WAV:INF] ++InterruptThreadOutputDMA()\n\r")));

    while(TRUE)
    {
        WaitForSingleObject(m_hOutputDMAInterrupt, INFINITE);

        Lock();

        __try
        {
            DMA_set_interrupt_mask(&g_OutputDMA);
            DMA_clear_interrupt_pending(&g_OutputDMA);

            InterruptDone(m_dwSysintrOutput);

            DMA_clear_interrupt_mask(&g_OutputDMA);

            if ( m_Dx == D0 )
            {
                // DMA Output Buffer is Changed by LLI
                if (m_nOutputBufferInUse == OUTPUT_DMA_BUFFER0)
                {
                    // Buffer0 DMA finished
                    // DMA start with Buffer 1
                    m_nOutputBufferInUse = OUTPUT_DMA_BUFFER1;
                }
                else
                {
                    // Buffer 1 DMA finished
                    // DMA start with Buffer 0
                    m_nOutputBufferInUse = OUTPUT_DMA_BUFFER0;
                }

                if(m_OutputDMAStatus & DMA_BIU)
                {
                    m_OutputDMAStatus &= ~DMA_STRTB;    // Buffer B just completed...
                    m_OutputDMAStatus |= DMA_DONEB;
                    m_OutputDMAStatus &= ~DMA_BIU;        // Buffer A is in use
                }
                else
                {
                    m_OutputDMAStatus &= ~DMA_STRTA;    // Buffer A just completed...
                    m_OutputDMAStatus |= DMA_DONEA;
                    m_OutputDMAStatus |= DMA_BIU;        // Buffer B is in use
                }

                OutputTransferred = TransferOutputBuffer(m_OutputDMAStatus);
            }
        }
        __except(GetExceptionCode()==STATUS_ACCESS_VIOLATION ?
               EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
        {
            WAV_ERR((_T("WAVDEV2.DLL:InterruptThreadOutputDMA() - EXCEPTION: %d"), GetExceptionCode()));
        }

        Unlock();
    }

    WAV_INF((_T("[WAV:INF] --InterruptThreadOutputDMA()\n\r")));
}

⌨️ 快捷键说明

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