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

📄 wav.cpp

📁 EP931X系列的WinCE声卡驱动源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
//  @parm   PBYTE | pBufOut | Pointer to the return value (DWORD).
//
//  @parm   DWORD | dwLenOut | Size of the return value variable (sizeof(DWORD)).
//
//  @parm   PDWORD | pdwActualOut | Unused
//
//  @rdesc  Returns TRUE for success, FALSE for failure
//
//  @xref   <t Wave Input Driver Messages> (WIDM_XXX) <nl>
//          <t Wave Output Driver Messages> (WODM_XXX)
//
// -----------------------------------------------------------------------------
extern "C" BOOL WAV_IOControl
(
    DWORD  dwOpenData, 
    DWORD  dwCode, 
    PBYTE  pBufIn,
    DWORD  dwLenIn, 
    PBYTE  pBufOut, 
    DWORD  dwLenOut,
    PDWORD pdwActualOut
)
{
    DWORD dwRet;
    PMMDRV_MESSAGE_PARAMS pParams = (PMMDRV_MESSAGE_PARAMS) pBufIn;
    AudioDriver *pAudioDrv;    


    //  set the error code to be no error first
    SetLastError(MMSYSERR_NOERROR);

    __try 
    {
        pAudioDrv = *(AudioDriver **)dwOpenData;
        if(dwCode == IOCTL_WAV_MESSAGE)
        {
            dwRet = pAudioDrv->WaveMessage((PMMDRV_MESSAGE_PARAMS) pBufIn);
        }
        else if(dwCode == IOCTL_MIX_MESSAGE && pAudioDrv->MixerEnabled())
        {
            dwRet = pAudioDrv->MixerMessage((PMMDRV_MESSAGE_PARAMS) pBufIn);
        }
        else if( dwCode == IOCTL_DSHAL_MESSAGE)
        {
            PRINTMSG(ZONE_IOCTL, (TEXT("WAV_IOControl: dwCode == IOCTL_DSHAL_MESSAGE.\r\n")));
            return(FALSE);
        }
        
        else
        {
            PRINTMSG
            (
                ZONE_IOCTL, 
                (
                    TEXT("Unsupported dwCode = 0x%08x in WAV_IOControl()\r\n"),
                    dwCode
                )
            );
            return(FALSE);
        }    

        //
        // Pass the return code back via pBufOut
        //
        if (pBufOut != NULL) 
        {
            *((DWORD*) pBufOut) = dwRet;
        }   


    } __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) 
    {

        RETAILMSG(1, (TEXT("EXCEPTION IN WAV_IOControl!!!!\r\n")));
    }   

    return TRUE;
}

//****************************************************************************
// AudioDriver::Initialize
//****************************************************************************
// Audio Driver Initialation routine.
// 
//

MMRESULT AudioDriver::Initialize(void)
{
    BOOL    bUseAC97;
    BOOL    bSetGPIO1, bClearGPIO8;

    HKEY    hKey;
    DWORD   dwRet;

    //
    // Open the WaveDev driver key.
    //
    RegOpenKeyEx
    ( 
        HKEY_LOCAL_MACHINE,
        TEXT("\\Drivers\\BuiltIn\\WaveDev"),
        0,
        0,
        &hKey
    ); 


    //
    // Check to see if we are using I2S or AC97.
    //
    bUseAC97  = ReadRegistryValue(hKey, TEXT("UseAC97"), 0);

    //
    // Check to see if we need to set GPIO 1 for the external unmute.
    //
    bSetGPIO1 = ReadRegistryValue(hKey, TEXT("SetGPIO1"), 0);


    //
    // The EDB9315 boards need GPIO8 to be cleared.
    //
    bClearGPIO8 = ReadRegistryValue(hKey, TEXT("ClearGPIO8"), 0);

    //
    // Close the registry key.
    //
    RegCloseKey( hKey);


    //
    // Initializes the proper codec type
    //
    if(bUseAC97)
    {
        //
        // Initialize the AC97 codec
        //
        dwRet = m_AC97.Initialize();
        if(MMSUCCESS(dwRet))
        {
            dwRet = m_AC97Mixer.Initialize(&m_AC97);
            m_pCodec = &m_AC97;
            m_pMixer = &m_AC97Mixer;
        }        
        if(!MMSUCCESS(dwRet))
        {
            ERRORMSG(ZONE_ERROR, (L"AudioDriver::Initialize: Failed to initialize AC97Codec\n" )) ;
        }
    }
    else
    {
        //  
        // In order to enable the audio section on the EDB9315 you must clear 
        // GPIO 8.
        //
        if(bClearGPIO8)
        {
            HalWriteCommonReg
            (
                GPIO_PBDDR, 
                0x1,
                0x1
            );
            HalWriteCommonReg
            (
                GPIO_PBDR, 
                0x1,
                0x0
            );
        }
        //
        // Initialize the I2S mixer
        //
        dwRet = m_I2S.Initialize();
        if(MMSUCCESS(dwRet))
        {
            m_pCodec = &m_I2S;
            m_pMixer = &m_I2SMixer;
        }        
        if(!MMSUCCESS(dwRet))
        {
            ERRORMSG(ZONE_ERROR, (L"AudioDriver::Initialize: Failed to initialize I2S Codec\n" )) ;
        }

        //
        // The EDB9301 uses EGPIO1 as a mute.
        //         
        if(bSetGPIO1)
        {
            HalWriteCommonReg
            (
                GPIO_PADDR, 
                0x2,
                0x2
            );
            HalWriteCommonReg
            (
                GPIO_PADR, 
                0x2,
                0x2
            );
        }
    }

    //
    // Initialize the Waveout class.
    //    
    if(MMSUCCESS(dwRet))
    {
        dwRet = m_WaveOut.Initialize(m_pCodec);
        if(!MMSUCCESS(dwRet))
        {
            ERRORMSG(ZONE_ERROR, (L"AudioDriver::Initialize: Failed to initialize gpWaveOut\n" )) ;
        }
    }        
    
    //
    // Initialize the Wavein class.
    //    
    if(MMSUCCESS(dwRet))
    {
        dwRet = m_WaveIn.Initialize(m_pCodec);
        if(!MMSUCCESS(dwRet))
        {
            ERRORMSG(ZONE_ERROR, (L"AudioDriver::Initialize: Failed to initialize gpWaveIn\n" )) ;
        }
    }        
    
    
    return dwRet;
}

//****************************************************************************
// AudioDriver::WaveMessage
//****************************************************************************
// Process all wavein/out messages.
// 
//
DWORD AudioDriver::WaveMessage(PMMDRV_MESSAGE_PARAMS pParams)
{
    DWORD   dwRet;
    switch (pParams->uMsg) 
    {

        case WODM_BREAKLOOP:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_BREAKLOOP\r\n")));
            dwRet = m_WaveOut.BreakLoop();
            break;

        case WODM_CLOSE:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_CLOSE\r\n")));
            dwRet = m_WaveOut.Close();
            break;

        case WODM_GETDEVCAPS:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_GETDEVCAPS\r\n")));
            dwRet = m_WaveOut.GetDevCaps((PWAVEOUTCAPS) pParams->dwParam1, pParams->dwParam2);
            break;

        case WODM_GETNUMDEVS:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_GETNUMDEVS\r\n")));
            dwRet = m_WaveOut.GetNumDev();
            break;

        case WODM_GETPITCH:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_GETPITCH\r\n")));
            dwRet = m_WaveOut.GetPitch();
            break;

        case WODM_GETPLAYBACKRATE:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_GETPLAYBACKRATE\r\n")));
            dwRet = m_WaveOut.GetPlaybackRate();
            break;

        case WODM_GETPOS:
            //PRINTMSG(ZONE_WODM, (TEXT("WODM_GETPOS\r\n")));
            dwRet = m_WaveOut.GetPosition((MMTIME *) pParams->dwParam1, pParams->dwParam2);
            break;

        case WODM_GETVOLUME:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_GETVOLUME\r\n")));
            dwRet = m_WaveOut.GetVolume((DWORD *) pParams->dwParam1, pParams->uDeviceId);
            break;

        case WODM_OPEN:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_OPEN\r\n")));
            
            dwRet = m_WaveOut.Open
            (
                (DWORD *)pParams->dwUser,
                (WAVEOPENDESC *)pParams->dwParam1, 
                pParams->dwParam2
            );
            break;

        case WODM_PAUSE:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_PAUSE\r\n")));
            dwRet = m_WaveOut.Pause();
            break;

        case WODM_PREPARE:
            // PRINTMSG(ZONE_WODM, (TEXT("WODM_PREPARE\r\n")));
            dwRet = m_WaveOut.Prepare();
            break;

        case WODM_RESET:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_RESET\r\n")));
            dwRet = m_WaveOut.Reset();
            break;

        case WODM_RESTART:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_RESTART\r\n")));
            dwRet = m_WaveOut.Restart();
            break;

        case WODM_SETPITCH:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_SETPITCH\r\n")));
            dwRet = m_WaveOut.SetPitch();
            break;

        case WODM_SETPLAYBACKRATE:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_SETPLAYBACKRATE\r\n")));
            dwRet = m_WaveOut.SetPlaybackRate();
            break;

        case WODM_SETVOLUME:
            PRINTMSG(ZONE_WODM, (TEXT("WODM_SETVOLUME\r\n")));
            dwRet = m_WaveOut.SetVolume
            ( 
                pParams->dwUser,
                pParams->dwParam1, 
                pParams->uDeviceId 
            );
            break;

        case WODM_UNPREPARE:
            //PRINTMSG(ZONE_WODM, (TEXT("WODM_UNPREPARE\r\n")));
            dwRet = m_WaveOut.Prepare();
            break;

        case WODM_WRITE:
            //PRINTMSG(ZONE_WODM, (TEXT("WODM_WRITE\r\n")));
            //dwRet = m_WaveOut.Write((WAVEHDR *)pParams->dwParam1, pParams->dwParam2);
            dwRet = m_WaveOut.Write((WAVEHDR *)pParams->dwParam1, sizeof(WAVEHDR));
            break;

        case WIDM_ADDBUFFER:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_ADDBUFFER\r\n")));
            dwRet = m_WaveIn.AddBuffer((PWAVEHDR)pParams->dwParam1, pParams->dwParam2 );
            break;

        case WIDM_CLOSE:
            //PRINTMSG(ZONE_WIDM, (TEXT("WIDM_CLOSE\r\n")));
            dwRet = m_WaveIn.Close();
            break;

        case WIDM_GETDEVCAPS:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_GETDEVCAPS\r\n")));
            dwRet = m_WaveIn.GetDevCaps((PWAVEINCAPS)pParams->dwParam1, pParams->dwParam2);
            break;

        case WIDM_GETNUMDEVS:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_GETNUMDEVS\r\n")));
            dwRet = m_WaveIn.GetNumDevs();
            break;

        case WIDM_GETPOS:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_GETPOS\r\n")));
            dwRet = m_WaveIn.GetPosition((MMTIME *) pParams->dwParam1, pParams->dwParam2);
            break;

        case WIDM_OPEN:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_OPEN\r\n")));
            dwRet =  m_WaveIn.Open((WAVEOPENDESC *)pParams->dwParam1, pParams->dwParam2);
            break;

        case WIDM_PREPARE:
            //PRINTMSG(ZONE_WIDM, (TEXT("WIDM_PREPARE\r\n")));
            dwRet =  m_WaveIn.Prepare();
            break;

        case WIDM_RESET:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_RESET\r\n")));
            dwRet = m_WaveIn.Reset();
            break;

        case WIDM_START:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_START\r\n")));
            dwRet = m_WaveIn.Start();
            break;

        case WIDM_STOP:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_STOP\r\n")));
            dwRet = m_WaveIn.Stop();
            break;

        case WIDM_UNPREPARE:
            PRINTMSG(ZONE_WIDM, (TEXT("WIDM_UNPREPARE\r\n")));
            dwRet = m_WaveIn.UnPrepare();
            break;

        default:
            dwRet = MMSYSERR_NOTSUPPORTED;
    }
    return dwRet;
}

//****************************************************************************
// AudioDriver::MixerMessage
//****************************************************************************
// Process all mixer messages.
// 
//
DWORD AudioDriver::MixerMessage(PMMDRV_MESSAGE_PARAMS pParams)
{
    DWORD dwRet;
    DWORD dwParam1, dwParam2;
    UINT uDeviceId;

    // pStream = (HSTREAM) pParams->dwUser;
    dwParam1 = pParams->dwParam1;
    dwParam2 = pParams->dwParam2;
    uDeviceId = pParams->uDeviceId;

    if (uDeviceId != 0) 
    {
        return MMSYSERR_BADDEVICEID;
    }


    switch (pParams->uMsg) 
    {
        // mixer API messages:
        // only 
        // only purpose of mixer handles at driver level is to provide a target for callbacks.
        // as such, only really need one handle per device. if client application(s) open more than one
        // mixer handle, the mixer API should MUX them, so driver only have has to manage a single instance.
        case MXDM_GETNUMDEVS:
            dwRet = 1;
            break;

        case MXDM_GETDEVCAPS:
            dwRet = m_pMixer->GetMixerCaps((PMIXERCAPS) dwParam1);
            break;

        case MXDM_OPEN:
            dwRet = m_pMixer->OpenMixerHandle((PDWORD) pParams->dwUser, (PMIXEROPENDESC) dwParam1, dwParam2);
            break;

        case MXDM_CLOSE:
            dwRet = m_pMixer->CloseMixerHandle(dwParam2);
            break;

        case MXDM_GETLINECONTROLS:
            dwRet = m_pMixer->GetMixerLineControls((PMIXERLINECONTROLS) dwParam1, dwParam2);
            break;

        case MXDM_GETLINEINFO:
            dwRet = m_pMixer->GetMixerLineInfo((PMIXERLINE) dwParam1, dwParam2);
            break;

        case MXDM_GETCONTROLDETAILS:
            dwRet = m_pMixer->GetMixerControlDetails((PMIXERCONTROLDETAILS) dwParam1, dwParam2);
            break;

        case MXDM_SETCONTROLDETAILS:
            dwRet = m_pMixer->SetMixerControlDetails((PMIXERCONTROLDETAILS) dwParam1, dwParam2);
            break;

        default:
            dwRet = MMSYSERR_NOTSUPPORTED;
            break;
    }
    return dwRet;
}

//****************************************************************************
// ReadRegistryValue
//****************************************************************************
// Read the DWORD Registry Value
// 
//
DWORD ReadRegistryValue(HKEY hKey, PTSTR szValueName, DWORD dwDefault)
{
    LONG    lStatus;
    ULONG   ulReturnValue;
    DWORD   dwValType = REG_DWORD;
    DWORD   dwValLen = 4;

    lStatus = RegQueryValueEx( hKey, szValueName, NULL, &dwValType, (PBYTE)&ulReturnValue, &dwValLen);
        
    if ((lStatus != ERROR_SUCCESS) || (dwValType != REG_DWORD)) 
    {           
        ulReturnValue = dwDefault;
    } 
 
    return ulReturnValue;
}

⌨️ 快捷键说明

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