📄 waveout.cpp
字号:
}
//****************************************************************************
// ConvertToCodecVolume
//****************************************************************************
//
// (usWaveVolume * usWaveVolume) * ucMinCodecVolume
// CodecVolume = ucMinCodecVolume - -----------------------------------
// (MAX_WAVE_VOLUME * MAX_WAVE_VOLUME)
//
// To get rid of the overflow possibilies, use the formula below.
//
//
UCHAR ConvertToCodecVolume
(
USHORT usVolume,
USHORT ucMinCodecVolume
)
{
UCHAR ucCodecVolume;
ULONG ulTemp;
ulTemp = (((ULONG)usVolume * (ULONG)usVolume + 1)>>24) * (ULONG)ucMinCodecVolume;
ucCodecVolume = ucMinCodecVolume - (UCHAR)(ulTemp >>8);
return(ucCodecVolume);
}
//****************************************************************************
// WaveOut::SetVolume
//****************************************************************************
// Called on WODM_SETVOLUME. Sets the codec volume.
// 0 is silence, 0xFFFF is full volume.
//
MMRESULT WaveOut::SetVolume
(
DWORD dwUser,
DWORD dwVolume,
UINT uDeviceId
)
{
FUNC_WAVEOUT((L"+WaveOut::SetVolume: Volume = 0x%08x\n", dwVolume));
MMRESULT mmRet;
ULONG ulRightVol, ulLeftVol;
if(m_pCodec->m_bPlaybackOpened && dwUser)
{
if(m_WaveFormat.nChannels == 1)
{
m_usLeftVolume = m_usRightVolume = (USHORT)(dwVolume & 0xFFFF);
}
else
{
m_usRightVolume = (USHORT)(dwVolume & 0xFFFF);
m_usLeftVolume = (USHORT)(dwVolume>>16);
}
m_pCodec->SetVolume
(
(ULONG)m_usRightVolume | ((ULONG)m_usRightVolume <<16),
(ULONG)m_usLeftVolume | ((ULONG)m_usLeftVolume <<16),
0
);
mmRet = MMSYSERR_NOERROR;
}
else if(uDeviceId == 0)
{
m_usMasterLeftVolume = m_usMasterRightVolume =
(USHORT)(dwVolume & 0xFFFF);
mmRet = MMSYSERR_NOERROR;
}
else
{
mmRet = MMSYSERR_BADDEVICEID;
}
//
// After setting the new volumes program the new wave out volume.
//
if(mmRet == MMSYSERR_NOERROR)
{
ulRightVol = ((ULONG)m_usRightVolume + (ULONG)m_usMasterRightVolume + 1) >>1;
ulLeftVol = ((ULONG)m_usLeftVolume + (ULONG)m_usMasterLeftVolume + 1) >>1;
m_pCodec->SetVolume
(
ulRightVol | (ulRightVol <<16),
ulLeftVol | (ulLeftVol <<16),
0
);
}
FUNC_WAVEOUT((L"-WaveOut::SetVolume\n"));
return(mmRet);
}
//****************************************************************************
// WaveOut::Write
//****************************************************************************
// Called on WODM_WRITE. Adds a buffer to the buffer list.
//
MMRESULT WaveOut::Write
(
WAVEHDR * pWaveHDR,
DWORD dwSize
)
{
//FUNC_WAVEOUT((L"+WaveOut::Write\n"));
//
// Make sure the specified wave header is large enough. If not then return
// an error.
//
if(dwSize < sizeof(WAVEHDR))
{
return(MMSYSERR_INVALPARAM);
}
//
// Make sure the wave header has been prepared. Return an error if it has
// not been prepared (which means that a page fault might happen when we
// try to access the wave header or the data to which it points to fill the
// DMA buffer at interrupt time).
//
//if(!(pWaveHDR->dwFlags & WHDR_PREPARED))
//{
// return(WAVERR_UNPREPARED);
//}
EnterCriticalSection( &m_CriticalSection);
//
// Add the buffer to the list of buffers.
//
AddBuffer(pWaveHDR);
//
// Start the wave playing.
//
if(!m_bIsPlaying || m_bIsPaused)
{
//
// If we add a buffer when we are paused we start back up again.
// These settings will cause DMA to start up.
//
m_bIsPaused = FALSE;
m_bIsPlaying = FALSE;
//
// Fill the DMA buffer
//
FillDMABuffer(0,m_ulDmaBufferSize);
}
//
// Wave is playing but the current DMA buffer has not been filled.
//
else if(m_bIsPlaying && !m_bIsPaused && m_dwPreviousStart != m_dwPreviousEnd)
{
//
// Fill the DMA buffer
//
FillDMABuffer(m_dwPreviousStart, m_dwPreviousEnd);
}
LeaveCriticalSection( &m_CriticalSection);
//FUNC_WAVEOUT((L"-WaveOut::Write\n"));
return( MMSYSERR_NOERROR);
}
//****************************************************************************
// ConvertBytesToWords
//****************************************************************************
// Converts a stream of bytes to words.
//
// pusDst - Signed 24 bit values right justified.
// pucSrc - Unsigned 8 bit values.
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertBytesToWords
(
PULONG pulDst,
PUCHAR pucSrc,
ULONG ulNumberOfBytes
)
{
ULONG ulCount;
char cTemp;
ULONG ulSamples = (ulNumberOfBytes>>2);
for(ulCount = 0; ulCount <ulSamples ; ulCount++)
{
cTemp = ((char)pucSrc[ulCount]) + 0x80;
pulDst[ulCount] = cTemp<<16;
}
}
//****************************************************************************
// ConvertShortsToWords
//****************************************************************************
// Converts a stream of bytes to words.
//
// pulDst - Signed 24 bit values right justified.
// pusSrc - Signed 16 bit values.
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertShortsToWords
(
PULONG pulDst,
PUSHORT pusSrc,
ULONG ulNumberOfBytes
)
{
//ULONG ulCount;
USHORT usTemp;
PUSHORT pusEnd = pusSrc + (ulNumberOfBytes>>1);
//ULONG ulSamples = (ulNumberOfBytes>>1);
//for(ulCount = 0; ulCount <ulSamples ; ulCount++)
//{
// usTemp = pusSrc[ulCount];
// pulDst[ulCount] = (ULONG)usTemp<<8;
//}
do
{
usTemp = *pusSrc++;
*pulDst++ = (ULONG)usTemp<<8;
}
while(pusSrc < pusEnd);
}
//****************************************************************************
// ConvertBytesToWordsMonoToStereo
//****************************************************************************
// Converts a stream of bytes to words.
//
// pulDst - Signed 24 bit values right justified.
// pucSrc - Unsigned 8 bit values.
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertBytesToWordsMonoToStereo
(
PULONG pulDst,
PUCHAR pucSrc,
ULONG ulNumberOfBytes
)
{
ULONG ulCount;
char cTemp;
ULONG ulSamples = (ulNumberOfBytes>>2);
for(ulCount = 0; ulCount <ulSamples ; ulCount++)
{
cTemp = ((char)*pucSrc++) + 0x80;
*pulDst++ = cTemp<<16;
*pulDst++ = cTemp<<16;
}
}
//****************************************************************************
// ConvertShortsToWordsMonoToStereo
//****************************************************************************
// Converts a stream of bytes to words.
//
// pulDst - Signed 24 bit values right justified.
// pusSrc - Signed 16 bit values.
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertShortsToWordsMonoToStereo
(
PULONG pulDst,
PUSHORT pusSrc,
ULONG ulNumberOfBytes
)
{
ULONG ulCount;
USHORT usTemp;
ULONG ulSamples = (ulNumberOfBytes>>1);
for(ulCount = 0; ulCount <ulSamples ; ulCount++)
{
usTemp = *pusSrc++;
*pulDst++ = (ULONG)usTemp<<8;
*pulDst++ = (ULONG)usTemp<<8;
}
}
//****************************************************************************
// ConvertBytesToShorts
//****************************************************************************
// Converts a stream of bytes to shorts.
//
// pusDst - Signed 16 bit values
// pucSrc - Unsigned 8 bit values
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertBytesToShorts
(
PUSHORT pusDst,
PUCHAR pucSrc,
ULONG ulNumberOfBytes
)
{
ULONG ulCount;
char cTemp;
ULONG ulSamples = (ulNumberOfBytes>>1);
for(ulCount = 0; ulCount <ulSamples ; ulCount++)
{
cTemp = ((char)pucSrc[ulCount]) + 0x80;
pusDst[ulCount] = cTemp<<8;
}
}
//****************************************************************************
// ConvertBytesToShortsMonoToStereo
//****************************************************************************
// Converts a stream of mono bytes to stereo shorts.
//
// pulDst - Stereo signed 16 bit values
// pucSrc - Mono Unsigned 8 bit values
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertBytesToShortsMonoToStereo
(
PULONG pulDst,
PUCHAR pucSrc,
ULONG ulNumberOfBytes
)
{
ULONG ulCount;
char cTemp;
ULONG ulSamples = (ulNumberOfBytes>>1);
for(ulCount = 0; ulCount <ulSamples ; ulCount++)
{
cTemp = ((char)pucSrc[ulCount]) + 0x80;
pulDst[ulCount] = ((ULONG)cTemp<<24) | (cTemp <<8);
}
}
//****************************************************************************
// ConvertShortsMonoToStereo
//****************************************************************************
// Converts a Stream of 16 bit mono sample to a stream of 16 Stereo samples.
//
// puDst - Stereo unsigned 16 bit values
// pucSrc - Mono Unsigned 8 bit values
// ulNumberOfBytes - Number of Source bytes.
//
void ConvertShortsMonoToStereo
(
PULONG pulDst,
PUSHORT pusSrc,
ULONG ulNumberOfBytes
)
{
ULONG ulCount;
USHORT usTemp;
ULONG ulSamples = (ulNumberOfBytes>>1);
for(ulCount = 0; ulCount <ulSamples ; ulCount++)
{
usTemp = pusSrc[ulCount];
pulDst[ulCount] = (usTemp<<16) | usTemp ;
}
}
//****************************************************************************
// WaveOut::FillDMABuffer
//****************************************************************************
// Copies wave data from the buffers associated with
// the wave headers that have been written to us (via the WODM_WRITE message)
// into the DMA buffer.
//
//
// dwStartPos = The Start position in the DMA buffer.
// dwEndPos = The End position in the DMA buffer.
// ulBytesToCopy = The number of bytes left
//
//
//
//
//
void WaveOut::FillDMABuffer
(
DWORD dwStartPos,
DWORD dwEndPos
)
{
BOOL bIsFirstFill = FALSE;
BOOL bIsFull = FALSE;
//
// If the entire buffer needs to be filled, then this is the first time
// (or the first time after a reset) that this function has been called.
// In that case, we must pre-fill the on-chip DMA buffer before we start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -