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

📄 waveout.cpp

📁 EP931X系列的WinCE声卡驱动源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
}

//****************************************************************************
// 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 + -