📄 waveout.cpp
字号:
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 + -