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

📄 hwctxt.cpp

📁 freesacle mx21下的声卡alc5620的驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            //----- 5. Make sure the audio isn't muted -----
            AudioMute(AUDIO_CH_OUT, FALSE);                 

            //----- 6. Start the DMA controller -----
            DDKDmacClearChannelIntr(m_DmaTxChannel);
            DDKDmacStartChan(m_DmaTxChannel);
            InterruptDone(m_dwSysintrOutput);
            
            UINT32 status;
            status = BSPAudioClearInterruptStatus(SSI_TRANSFER_TX, SSI_CHANNEL0);

            if(CSP_BITFEXT(status, SSI_SISR_TFS) == SSI_SISR_TFS_FS_OCCUR)
            {
                BSPSetSwap(TRUE);
            }
            else
            {
                BSPSetSwap(FALSE);
            }

           // call back BSP function to enable the output
           BSPAudioStartOutput(TRUE);
            
            // Set time slot mask registers (Slot 0 - Tag, Slot3 - PCM Left and Slot 4 - PCM Right)
           // Set Slot 0 (TAG) value to indicate Frame Valid, PCM Left and PCM Right
           BSPSetSlotTag(0x9800) ; // Binary:1001 1000 0000 0000
          

            // Wait for DMA to start
            while(DDKDmacGetTransSize(m_DmaTxChannel) == 0);
            // Set DMA for next buffer
            DDKDmacSetSrcAddress(m_DmaTxChannel, m_DmaTxBuffer[1]);

            DEBUGMSG(ZONE_MISC, (TEXT("Output DMA transferred: %d\r\n"),
                                DDKDmacGetTransSize(m_DmaTxChannel)));
        }
        else    // We didn't transfer any data, so DMA wasn't enabled
        {
            m_OutputDMARunning = FALSE;
        }
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-StartOutputDMA\r\n")));
    return TRUE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       StopOutputDMA
//
//  DESCRIPTION:    Stops playback DMA
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  None
//
//------------------------------------------------------------------------------
void HardwareContext::StopOutputDMA()
{
    //----- 1. If the output DMA is running, stop it -----
    if(m_OutputDMARunning)
    {
       // BSPAudioStartOutput(FALSE);


        DDKDmacDisableChannelIntr(m_DmaTxChannel);
        DDKDmacStopChan(m_DmaTxChannel);
        DDKDmacClearChannelIntr(m_DmaTxChannel);

        AudioMute(AUDIO_CH_OUT, TRUE);

        m_OutputDMARunning = FALSE;
        DEBUGMSG(ZONE_MISC, (TEXT("Stopped output DMA\r\n")));
    }
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       StartInputDMA
//
//  DESCRIPTION:    Start recording DMA
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  None
//
//------------------------------------------------------------------------------
BOOL HardwareContext::StartInputDMA()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+StartInputDMA\r\n")));

    if(!m_InputDMARunning)
    {
        //----- 1. Initialize our buffer counters -----
        // For now, pretend input dma is running in case we accidentally get reentered
        m_InputDMARunning = TRUE;
        m_InBytes[0] = 0;
        m_InBytes[1] = 0;
        m_RxBufIndex = 0;

        //----- 2. Configure the channel for record -----
        DDKDmacSetRepeatType(m_DmaRxChannel, DMAC_REPEAT_FOREVER);
        DDKDmacSetDestAddress(m_DmaRxChannel, m_DmaRxBuffer[0]);

        //----- 3. Make sure the audio isn't muted -----
        AudioMute(AUDIO_CH_IN, FALSE);                  

        //----- 4. Start the input DMA -----
        DDKDmacClearChannelIntr(m_DmaRxChannel);
        DDKDmacStartChan(m_DmaRxChannel);
        DDKDmacEnableChannelIntr(m_DmaRxChannel);
        InterruptDone(m_dwSysintrInput);

        BSPAudioClearInterruptStatus(SSI_TRANSFER_RX, SSI_CHANNEL0);
        BSPAudioStartInput(TRUE);

        // Wait for DMA to start
        while(DDKDmacGetTransSize(m_DmaRxChannel) == 0);
        // Set DMA for next buffer
        DDKDmacSetDestAddress(m_DmaRxChannel, m_DmaRxBuffer[1]);
        
        DEBUGMSG(ZONE_MISC, (TEXT("Started input DMA\r\n")));
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-StartInputDMA\r\n")));
    return TRUE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       StopInputDMA
//
//  DESCRIPTION:    Stops recording DMA
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  None
//
//------------------------------------------------------------------------------
void HardwareContext::StopInputDMA()
{
    if(m_InputDMARunning)
    {
        BSPAudioStartInput(FALSE);

        DDKDmacDisableChannelIntr(m_DmaRxChannel);
        DDKDmacStopChan(m_DmaRxChannel);
        DDKDmacClearChannelIntr(m_DmaRxChannel);

        AudioMute(AUDIO_CH_IN, TRUE);       
        
        m_InputDMARunning = FALSE;

        DEBUGMSG(ZONE_MISC, (TEXT("Stopped input DMA\r\n")));
    }
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       GetInterruptThreadPriority
//
//  DESCRIPTION:    Reads the registry entries to determine the priority
//                  of the audio interrupt service thread
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  priority
//
//------------------------------------------------------------------------------
DWORD HardwareContext::GetInterruptThreadPriority()
{
    HKEY hDevKey;
    DWORD dwValType;
    DWORD dwValLen;
    DWORD dwPrio = 249; // Default priority

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+GetInterruptThreadPriority\r\n")));

    hDevKey = OpenDeviceKey((LPWSTR)m_DriverIndex);
    if (hDevKey)
    {
        dwValLen = sizeof(DWORD);
        RegQueryValueEx(
                       hDevKey,
                       TEXT("Priority256"),
                       NULL,
                       &dwValType,
                       (PUCHAR)&dwPrio,
                       &dwValLen);
        RegCloseKey(hDevKey);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-GetInterruptThreadPriority: dwPrio=%d\r\n"), dwPrio));
    return dwPrio;
}
//------------------------------------------------------------------------------
//
// Function:       InitInterruptThread()
//
// Description:    Initializes the IST for handling DMA interrupts.
//
// Returns:        Boolean indicating success
//
//------------------------------------------------------------------------------
BOOL HardwareContext::InitInterruptThread()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+InitInterruptThread\r\n")));

    m_hAudioInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    if(!m_hAudioInterrupt)
    {
        ERRORMSG(ZONE_ERROR, (TEXT("Unable to create interrupt event\r\n")));
        return(FALSE);
    }
      
    if(!InterruptInitialize(m_dwSysintrOutput, m_hAudioInterrupt, NULL, 0))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("Unable to initialize output interrupt\r\n")));
        return FALSE;
    }
    if(!InterruptInitialize(m_dwSysintrInput, m_hAudioInterrupt, NULL, 0))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("Unable to initialize input interrupt\r\n")));
        return FALSE;
    }
    DEBUGMSG(ZONE_INTERRUPT, (TEXT("m_dwSysintrInput = %d m_dwSysintrOutput = %d\r\n"),
                                m_dwSysintrInput, m_dwSysintrOutput));

    m_hAudioInterruptThread  = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
                                            0,
                                            (LPTHREAD_START_ROUTINE)CallInterruptThread,
                                            this,
                                            0,
                                            NULL);
    if(!m_hAudioInterruptThread)
    {
        ERRORMSG(ZONE_ERROR, (TEXT("Unable to create interrupt thread\r\n")));
        return FALSE;
    }

    // Bump up the priority since the interrupt must be serviced immediately.
    CeSetThreadPriority(m_hAudioInterruptThread, GetInterruptThreadPriority());

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-InitInterruptThread\r\n")));
    return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function:       PowerUp()
//
// Description:    Powers up the audio codec chip.
//
// Notes:          Currently, this function is unimplemented because
//                 the audio codec chip is ONLY powered up when the 
//                 user wishes to play or record.  The AudioMute() function
//                 handles the powerup sequence.
//
// Returns:        Boolean indicating success
//
//------------------------------------------------------------------------------
void HardwareContext::PowerUp()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+PowerUp\r\n")));

    // Reload current gain settings
    SetOutputGain(m_dwOutputGain);
    SetInputGain(m_dwInputGain);
    SetOutputMute(m_fOutputMute);
    SetInputMute(m_fInputMute);
    
    AudioMute((AUDIO_CH_OUT | AUDIO_CH_IN), FALSE);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-PowerUp\r\n")));    
}
//------------------------------------------------------------------------------
//
// Function:       PowerDown()
//
// Description:    Powers down the audio codec chip.
//
// Notes:          Even if the input/output channels are muted, this
//                 function powers down the audio codec chip in order
//                 to conserve battery power.
//
// Returns:        Boolean indicating success
//
//------------------------------------------------------------------------------
void HardwareContext::PowerDown()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+PowerDown\r\n")));
   // StopOutputDMA();

    AudioMute((AUDIO_CH_OUT | AUDIO_CH_IN), TRUE);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("-PowerDown\r\n")));
}


//############################################ Helper Functions #############################################
//------------------------------------------------------------------------------
//
//  FUNCTION:       TransferOutputBuffer
//
//  DESCRIPTION:    Actual function to transfer playback data from 
//                  the indicated buffer to DMA. 
//                  Called by TransferOutputBuffers
//
//  PARAMETERS:     
//                  bufIndex - index of playback buffer to empty
//
//  RETURNS:        
//                  Number of bytes transferred from buffer
//
//------------------------------------------------------------------------------
UINT32 HardwareContext::TransferOutputBuffer(UINT8 bufIndex)
{
    ULONG BytesTransferred = 0;

    UINT8 *pBufferStart = (UINT8 *)m_Output_pbDMA_PAGES[bufIndex];
    UINT8 *pBufferEnd = pBufferStart + AUDIO_DMA_PAGE_SIZE;
    UINT8 *pBufferLast;

    __try
    {
        pBufferLast = m_OutputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd, NULL);
        BytesTransferred = m_OutBytes[bufIndex] = pBufferLast-pBufferStart;

        // Enable if you need to clear the rest of the DMA buffer
        StreamContext::ClearBuffer(pBufferLast,pBufferEnd);
        
        //if(BytesTransferred == 0)
        //    DmacSetRepeatType(m_DmaTxChannel, DMAC_REPEAT_DISABLED);
        //else
            DDKDmacSetSrcAddress(m_DmaTxChannel, m_DmaTxBuffer[bufIndex]);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("WAVDEV2.DLL:TransferOutputBuffer() - EXCEPTION: %d"), GetExceptionCode()));
    }

    return BytesTransferred;
}
//------------------------------------------------------------------------------
//
//  FUNCTION:       TransferOutputBuffers
//
//  DESCRIPTION:    Calls TransferOutputBuffer to transfer data from 
//                  playback buffer to DMA. Also toggles the current
//                  buffer index to acheive double buffering. Stops
//                  output dma if nothing is transferred for 2 
//                  buffers consecutively.
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  Number of bytes transferred from buffer
//
//------------------------------------------------------------------------------
UINT32 HardwareContext::TransferOutputBuffers(void)
{
    UINT32 BytesTransferred = 0;
    UINT32 DmaTransferred = 0;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+TransferOutputBuffers\r\n")));
    
    //DmaTransferred = DmacGetTransSize(m_DmaRxChannel);
    //RETAILMSG(1, (TEXT("DmaTransferred(%d).\r\n"), DmaTransferred));
    
    BytesTransferred += TransferOutputBuffer(m_TxBufIndex);
    m_TxBufIndex = (m_TxBufIndex == 0)? 1 : 0;
    
    //for( DmaTransferred = 0; DmaTransferred < 1000000000; DmaTransferred++ );
    
       
    //RETAILMSG(1, (TEXT("HardwareContext::TransferOutputBuffers(%d).\r\n"), BytesTransferred));
    
    // If it was our interrupt, but we weren't able to transfer any bytes
    // (e.g. no full buffers ready to be emptied)
    // and all the output DMA buffers are now empty, then stop the output DMA
    if(m_OutBytes[0] + m_OutBytes[1] == 0)
    {
        StopOutputDMA();
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-TransferOutputBuffers: BytesTransferred=%d\r\n"), BytesTransferred));

    return BytesTransferred;
}

⌨️ 快捷键说明

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