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

📄 waveout.cpp

📁 EP931X系列的WinCE声卡驱动源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    m_bIsPaused                 = FALSE;
    
    MarkAllAsDone(m_pWaveHead);
    RemoveCompleteBlocks();
    //if(MMSUCCESS(mmRet))
    //{
    //    m_pCodec->StopPlayback(0);
    //    m_Dma.Stop();
    //    ASSERT(MMSUCCESS(mmRet));
    //}        

    //mmRet = m_Dma.Flush();
    //ASSERT(MMSUCCESS(mmRet));
    
    //
    // While the wave driver is not playing, mute the codec.
    //
    //mmRet = m_pAC97->PokeAC97
    //(
    //    AC97_MASTER_VOLUME , 
    //    1, 
    //    0x8080
    //);
    ASSERT(MMSUCCESS(mmRet));

    LeaveCriticalSection( &m_CriticalSection);
    FUNC_WAVEOUT((L"-WaveOut::Close\n"));
    return(mmRet);    
}

//****************************************************************************
// WaveOut::BreakLoop
//****************************************************************************
// Called on WODM_BREAKLOOP
// 
//
MMRESULT WaveOut::BreakLoop()
{
    FUNC_WAVEOUT((L"+WaveOut::BreakLoop\n"));
    WAVEHDR     *pWave;
    BOOL        bMarkDone;


    EnterCriticalSection( &m_CriticalSection);
    
    //
    // Set the loop count to zero so that we will not loop back when we reach
    // the end of the loop and so that the wave headers will be returned as
    // they are consumed.
    //
    m_dwLoopCount = 0;
    
    
    //
    // Any Wave headers before the Current one we need to mark as done.
    //
    bMarkDone     = TRUE;
    

    //
    // Mark as done.
    //    
    pWave = m_pWaveHead;
    while (pWave != NULL) 
    {
        if(bMarkDone)
        {
            MARK_BUFFER_DONE(pWave);
        }
        
        if(pWave->lpNext == m_pWaveNext)
        {
            bMarkDone = FALSE;
        }
        MARK_BUFFER_NOT_INLOOP(pWave);
        pWave = pWave->lpNext;
    }   

    LeaveCriticalSection( &m_CriticalSection);
    
    
    FUNC_WAVEOUT((L"-WaveOut::BreakLoop\n"));
    return( MMSYSERR_NOERROR);    
}

//****************************************************************************
// WaveOut::GetDevCaps
//****************************************************************************
// Called on WODM_GETDEVCAPS.
// 
//
MMRESULT WaveOut::GetDevCaps
(
    PWAVEOUTCAPS    pCaps,
    DWORD           dwSize
)
{
    FUNC_WAVEOUT((L"+WaveOut::GetDevCaps\n"));
    MMRESULT mmRet = MMSYSERR_NOERROR;

    if (pCaps == NULL  || dwSize < sizeof(WAVEOUTCAPS))
    {
             //
             // If pCaps == NULL, we are requesting if the driver PDD
             // is capable of this mode at all.  In other words, if
             // APIDIR == WAPI_IN, we return no error if input is
             // supported, and MMSYSERR_NOTSUPPORTED otherwise.  Since
             // Odo has both, we return MMSYSERR_NOERROR regardless.
        mmRet = MMSYSERR_NOTSUPPORTED;
    }
    
    if(MMSUCCESS(mmRet))
    {
    
        //
        // Fill in the DevCaps here.
        //
        pCaps->wMid = MM_CRYSTAL;               // (MMREG.H)  Replace MM_MICROSOFT.
        pCaps->wPid = MM_CRYSTAL_EP9312_WAVEOUT;
        pCaps->vDriverVersion = 0x0001;
        wsprintf (pCaps->szPname, TEXT("EP9312 Audio (%hs)"), __DATE__);
        pCaps->dwFormats =   WAVE_FORMAT_1M08 | WAVE_FORMAT_1M16 |   // 11km8/16
                             WAVE_FORMAT_1S08 | WAVE_FORMAT_1S16 |   // 11ks8/16
                             WAVE_FORMAT_2M08 | WAVE_FORMAT_2M16 |   // 22km8/16
                             WAVE_FORMAT_2S08 | WAVE_FORMAT_2S16 |   // 22ks8/16
                             WAVE_FORMAT_4M08 | WAVE_FORMAT_4M16 |   // 44km8/16
                             WAVE_FORMAT_4S08 | WAVE_FORMAT_4S16;    // 44ks8/16

        pCaps->dwSupport = WAVECAPS_VOLUME | 
                           WAVECAPS_LRVOLUME | 
                           WAVECAPS_SAMPLEACCURATE;
    }                           

    FUNC_WAVEOUT((L"-WaveOut::GetDevCaps\n"));
    return( mmRet);    
}

//****************************************************************************
// WaveOut::GetPosition
//****************************************************************************
// Called on WODM_GETPOS
// 
//
MMRESULT WaveOut::GetPosition
(
    MMTIME  * pTime,
    DWORD     dwSize
)
{
    //FUNC_WAVEOUT((L"+WaveOut::GetPosition\n"));
    //DWORD       dwDMAPos;
    MMRESULT    mmRet;
    DWORD       dwBytePosition;
    
    if (IsBadWritePtr((PVOID)pTime, sizeof(MMTIME))) 
    {
        PRINTMSG
        (
            ZONE_WARN, 
            (
                TEXT("WARNING : WaveOut::GetPosition was passed a bad pointer (0x%X)\r\n"),
                pTime
            )
        );
        mmRet = MMSYSERR_INVALPARAM;
    } 
    else 
    {

        //
        // Get enough information about the current position.
        //
        //EnterCriticalSection( &m_CriticalSection);
        

        dwBytePosition  = m_dwBytePosition;
        //dwDMAPos        = m_Dma.CurrentPosition();
        //LeaveCriticalSection( &m_CriticalSection);

        #if 0
        if(m_bIsPlaying)
        {
            if(dwDMAPos > (BUFFER_SIZE/2))
            {
                dwDMAPos -=(BUFFER_SIZE/2);
            }
        
            //
            // Here is the byte position.  Remember that we may need to
            // divide by to if we are playing 8 bits samples.
            // 
            if(m_WaveFormat.wBitsPerSample == 16)
            {        
                dwBytePosition += dwDMAPos>>1;
            }
            else
            {            
                dwBytePosition += (dwDMAPos >>2);
            }            
        }
        #endif // 0

        switch (pTime->wType) 
        {
            case TIME_BYTES:
                pTime->u.cb = dwBytePosition;
                break;

            case TIME_SAMPLES:
                pTime->u.sample = (dwBytePosition * 8) / 
                    (m_WaveFormat.nChannels * m_WaveFormat.wBitsPerSample);
                break;

            case TIME_MS:
                if (m_WaveFormat.nAvgBytesPerSec != 0)
                    pTime->u.ms = (dwBytePosition * 1000) / m_WaveFormat.nAvgBytesPerSec;
                else  
                {
                    pTime->wType = TIME_BYTES;
                    pTime->u.cb = dwBytePosition;
                }
                break;

            case TIME_MIDI:
            case TIME_TICKS:
            case TIME_SMPTE:
                //
                // We don't support these, so return TIME_BYTES instead.
                //
                pTime->wType = TIME_BYTES;
                pTime->u.cb = dwBytePosition;
                break;
        }
        mmRet = MMSYSERR_NOERROR;
    }


    
    //FUNC_WAVEOUT((L"-WaveOut::GetPosition\n"));
    return( mmRet);    
}

//****************************************************************************
// WaveOut::GetVolume
//****************************************************************************
// Called on WODM_GETVOLUME
// 
//
MMRESULT WaveOut::GetVolume
(
    DWORD       *pdwVolume,
    UINT        uDeviceId
)
{
    MMRESULT  mmRet;

    FUNC_WAVEOUT((L"+WaveOut::GetVolume\n"));
    
    //
    // Save off the volume.
    //
    if(m_pCodec->m_bPlaybackOpened)
    {
        if(m_WaveFormat.nChannels == 1)
        {
            *pdwVolume = (ULONG)m_usRightVolume;

        }
        else                        
        {
            *pdwVolume = (ULONG)m_usRightVolume | ((ULONG)m_usLeftVolume << 16);
        }
        mmRet = MMSYSERR_NOERROR;
    }    
    else if(uDeviceId == 0)
    {
        *pdwVolume = (ULONG)m_usMasterRightVolume | ((ULONG)m_usMasterLeftVolume<<16);
    }
    else
    {
        mmRet = MMSYSERR_BADDEVICEID;        
    }

    
    FUNC_WAVEOUT((L"-WaveOut::GetVolume\n"));
    return( mmRet);    
}


//****************************************************************************
// WaveOut::Pause
//****************************************************************************
// Called on WODM_PAUSE.
// 
//
MMRESULT WaveOut::Pause()
{
    FUNC_WAVEOUT((L"+WaveOut::Pause\n"));
    MMRESULT mmRet = MMSYSERR_NOERROR;
    EnterCriticalSection( &m_CriticalSection);

    //
    // Check to see if we are currently playing.
    //    
    if(m_bIsPlaying && !m_bIsPaused)
    {
        mmRet = m_Dma.Stop();
        Sleep(1);
        m_pCodec->StopPlayback(0);
    }

    //
    // Mark the wave device as being paused.
    //
    m_bIsPaused = TRUE;

    LeaveCriticalSection( &m_CriticalSection);
    FUNC_WAVEOUT((L"-WaveOut::Pause\n"));
    return(mmRet);    
}

//****************************************************************************
// WaveOut::Reset
//****************************************************************************
// Called on WODM_RESET.  Return all buffers to applications and resets 
// wave out interface.
// 
//
MMRESULT WaveOut::Reset()
{
    FUNC_WAVEOUT((L"+WaveOut::Reset\n"));
    MMRESULT    mmRet = MMSYSERR_NOERROR;

    //
    // Make sure nobody else messes with the wave header lists.
    //
    EnterCriticalSection( &m_CriticalSection);
    
    if(m_bIsPlaying && !m_bIsPaused)
    {
        mmRet = m_Dma.Stop();
        Sleep(1);
        m_pCodec->StopPlayback(0);
        m_bIsPlaying = FALSE;
    }

    
    __try 
    {
        //
        // All queued blocks should be marked as DONE.
        //
        MarkAllAsDone(m_pWaveHead);
        MarkAllAsNotInLoop(m_pWaveHead);
        
        m_bIsPlaying        = FALSE;
        m_bIsPaused         = FALSE;
        m_dwLoopCount       = 0;
        m_dwBytePosition    = 0;
        m_dwPreviousStart   = 0;
        m_dwPreviousEnd     = 0;

        //
        // Do all the callbacks to clean up.
        //
        RemoveCompleteBlocks();
    } 
    __except(EXCEPTION_EXECUTE_HANDLER) 
    {
        ERRMSG((L"Error in WAVEDEV Reset.\r\n"));
        //InitGSI(WAPI_OUT);
    }
    
    LeaveCriticalSection( &m_CriticalSection);


    FUNC_WAVEOUT((L"-WaveOut::Reset\n"));
    return( MMSYSERR_NOERROR);    
}

//****************************************************************************
// WaveOut::Restart
//****************************************************************************
// Called on WODM_RESTART.  Start the WaveOut interface after a WODM_PAUSE
//
MMRESULT WaveOut::Restart()
{
    FUNC_WAVEOUT((L"+WaveOut::Restart\n"));
    MMRESULT    mmRet =MMSYSERR_NOERROR;

    //
    // If the wave task is not currently playing data but should be (i.e. there
    // are wave headers but the DSP task is not executing), then start the DSP
    // task.  Return an error if the DSP task can not be started (which should
    // not happen).
    //
    if(!m_bIsPaused)
    {
        m_pCodec->StartPlayback(0);
        Sleep(1);
        mmRet = m_Dma.Start();
    }

    //
    // Mark the wave device as being not paused.
    //
    m_bIsPaused  = FALSE;
    m_bIsPlaying = TRUE;
    
    FUNC_WAVEOUT((L"-WaveOut::Restart\n"));
    return( MMSYSERR_NOERROR);    

⌨️ 快捷键说明

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