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

📄 wavepdd.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
📖 第 1 页 / 共 4 页
字号:
static MMRESULT
PddMsg_Open(
    WAPI_INOUT apidir,
    LPWAVEFORMATEX lpFormat,
    BOOL bQueryFormatOnly
    )
{
    BSS_FUNC_WPDD("+PddMsg_Open");

    BOOL fBadFormat = TRUE;
    
	if (apidir == WAPI_OUT) {
		if ((lpFormat->wFormatTag == WAVE_FORMAT_PCM) && 
			(lpFormat->nChannels == 2) && 
			(lpFormat->nSamplesPerSec == 8000) && 
			(lpFormat->wBitsPerSample == 16)) {
			fBadFormat = FALSE;			
		}
	}
	else {
		if ((lpFormat->wFormatTag == WAVE_FORMAT_PCM) && 
			(lpFormat->nChannels == 1) && 
			(lpFormat->nSamplesPerSec == 8000) && 
			((lpFormat->wBitsPerSample == 8) || (lpFormat->wBitsPerSample == 16))) {
			fBadFormat = FALSE;
		}
	}

	if (fBadFormat) {
		return WAVERR_BADFORMAT;
	}
    
    //
    // Only checking if format is supported
    //
    if (bQueryFormatOnly) {
        BSS_FUNC_WPDD("-PddMsg_Open");
        return MMSYSERR_NOERROR;
    }

	// If driver is not ready, return error immediately
	DWORD dwRet = WaitForSingleObject(g_hReadyEvent, 0);
	if (WAIT_OBJECT_0 != dwRet) {
		SetLastError(ERROR_NOT_READY);
		return MMSYSERR_NOTENABLED;
	}

    LOCK_STREAM_INFO(apidir);

    if (g_StreamInfo[apidir].bOpened) {
        UNLOCK_STREAM_INFO(apidir);
        BSS_FUNC_WPDD("-PddMsg_Open");
        return MMSYSERR_ALLOCATED;
    }

	if (! g_fInitSco) {
    	// SCO has not been initialized.
    	UNLOCK_STREAM_INFO(apidir);
		SetLastError(ERROR_NOT_READY);
        return MMSYSERR_NOTENABLED;
    }

    g_StreamInfo[apidir].bOpened = TRUE;
    g_StreamInfo[apidir].wfx = *lpFormat;

    UNLOCK_STREAM_INFO(apidir);

    return MMSYSERR_NOERROR;
}


// -----------------------------------------------------------------------------
//                              PddMsg_Close
// -----------------------------------------------------------------------------
static MMRESULT 
PddMsg_Close(
    WAPI_INOUT apidir
    )
{
    BSS_FUNC_WPDD("+PddMsg_Close");

    LOCK_STREAM_INFO(apidir);
    g_StreamInfo[apidir].bOpened = FALSE;
    UNLOCK_STREAM_INFO(apidir);

    BSS_FUNC_WPDD("-PddMsg_Close");
    return MMSYSERR_NOERROR;
}


// -----------------------------------------------------------------------------
//                          PddMsg_OutGetVolume
// TODO: send a volume control command to the device.
// see docs for waveOutSetVolume on how to intepret ulVolume
// -----------------------------------------------------------------------------
static MMRESULT 
PddMsg_OutGetVolume(
    PULONG pulVolume
    )
{
    BSS_FUNC_WPDD("+PddMsg_OutGetVolume");
    *pulVolume = g_dwVolume;
    BSS_FUNC_WPDD("-PddMsg_OutGetVolume");
    return MMSYSERR_NOERROR;
}


// -----------------------------------------------------------------------------
//                          PddMsg_OutSetVolume
// TODO: send a volume control command to the device.
// see docs for waveOutSetVolume on how to intepret ulVolume
// -----------------------------------------------------------------------------
static MMRESULT 
PddMsg_OutSetVolume(
    ULONG ulVolume
    )
{
    BSS_FUNC_WPDD("+PddMsg_OutSetVolume :: doesn't actually do any real work");
    g_dwVolume = ulVolume;
    BSS_FUNC_WPDD("-PddMsg_OutSetVolume");
    return MMSYSERR_NOERROR;
}


// -----------------------------------------------------------------------------
//                          PDD_AudioPowerHandler
// -----------------------------------------------------------------------------
VOID
PDD_AudioPowerHandler(
    BOOL power_down
   )
{
    //
    // Handle any power up/down issues here. 
    //
}

DWORD WINAPI 
ScoInitThread(
	LPVOID pv
	)
{
	//
    // init SCO layer
    //
    int ret = sco_InitializeOnce();
    if (ret) {
        BSS_ERRMSG1("sco_InitializeOnce FAILED %d", ret);
        return ret;
    }

    //
    // create SCO layer instance
    //
    ret = sco_CreateDriverInstance();
    if (ret) {
        BSS_ERRMSG1("sco_CreateDriverInstance FAILED %d", ret);
        return ret;
    }

    //
    // install callbacks and get interface functions
    //
    SCO_CALLBACKS callbacks = {0};

    callbacks.DataPacketDown    = PddSco_DataPacketDown;
    callbacks.DataPacketUp      = PddSco_DataPacketUp;
    callbacks.PacketsCompleted  = NULL;
    callbacks.StackEvent        = PddSco_StackEvent;

    ret = sco_Bind(NULL, &callbacks, &g_ScoIntf);
    if (ret) {
        BSS_ERRMSG1("sco_Bind FAILED %d", ret);
        return ret;
    }

    SetEvent(g_hReadyEvent);
    
	return 0;
}

// -----------------------------------------------------------------------------
//                              PDD_AudioInitialize
// -----------------------------------------------------------------------------
BOOL 
PDD_AudioInitialize(
    DWORD dwIndex   
   )
{
    BSS_FUNC_WPDD("+PDD_AudioInitialize");

    LPTSTR pszRegKey = (LPTSTR) dwIndex;

    memset(g_StreamInfo, 0, sizeof(g_StreamInfo));
    memset(g_hAudioEvents, 0, sizeof(g_hAudioEvents));
    g_hReadyEvent		= 0;
    g_dwVolume          = 0;
    g_dwRxBufferLen     = 0;
    g_dwRxBufferStart   = 0;
    g_dwTxPacketsToSend = 0;
    g_dwScoPacketSize   = 0;
    g_usScoConnHandle   = 0;
    g_pTxBuffer			= NULL;
    g_fInitSco			= FALSE;

    InitializeCriticalSection(&(g_csStreamInfo[WAPI_IN]));
    InitializeCriticalSection(&(g_csStreamInfo[WAPI_OUT]));
    InitializeCriticalSection(&g_csRxBuffer);
    InitializeCriticalSection(&g_csTxBuffer);
    InitializeCriticalSection(&g_csPddWaveProcLock);

    //
    // create events
    //
    int i;
    for (i = 0; i < NUM_AUDIO_EVENTS; i++)
    {
        g_hAudioEvents[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (!g_hAudioEvents[i]) {
            BSS_ERRMSG("CreateEvent FAILED");
            return FALSE;
        }
    }
    
    g_hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (! g_hReadyEvent) {
        BSS_ERRMSG("CreateEvent FAILED");

        // Clean up what has already been initialized
        for (i = 0; i < NUM_AUDIO_EVENTS; i++)
	        CloseHandle(g_hAudioEvents[i]);
        
        return FALSE;
    }    

	//
	// Start SCO Initialization thread
	//
    HANDLE hThread = CreateThread(NULL, 0, ScoInitThread, NULL, 0, NULL);
    if (NULL == hThread) {
    	BSS_ERRMSG("CreateThread FAILED");
    	
    	// Clean up what has already been initialized
	    for (i = 0; i < NUM_AUDIO_EVENTS; i++)
	        CloseHandle(g_hAudioEvents[i]);
	    CloseHandle(g_hReadyEvent);
    	
    	return FALSE;
    }
    	
	CloseHandle(hThread);    

    BSS_FUNC_WPDD("-PDD_AudioInitialize (SUCCESS)");
    return TRUE;
}


// -----------------------------------------------------------------------------
//                          PDD_AudioDeinitialize
// -----------------------------------------------------------------------------
VOID 
PDD_AudioDeinitialize(
    VOID
    )
{
    int i;
    BSS_FUNC_WPDD("-PDD_AudioDeinitialize");

    DeinitSco ();

	sco_Unbind();
    sco_CloseDriverInstance();
    sco_UninitializeOnce();
    memset(&g_ScoIntf, 0, sizeof(g_ScoIntf));

    for (i = 0; i < NUM_AUDIO_EVENTS; i++)
    {
        if (g_hAudioEvents[i]) {
            CloseHandle(g_hAudioEvents[i]);
            g_hAudioEvents[i] = NULL;
        }
    }
    CloseHandle(g_hReadyEvent);
    g_hReadyEvent = NULL;

    DeleteCriticalSection(&g_csPddWaveProcLock);
    DeleteCriticalSection(&g_csTxBuffer);
    DeleteCriticalSection(&g_csRxBuffer);
    DeleteCriticalSection(&(g_csStreamInfo[WAPI_OUT]));
    DeleteCriticalSection(&(g_csStreamInfo[WAPI_IN]));

    BSS_FUNC_WPDD("-PDD_AudioDeinitialize");
}



// -----------------------------------------------------------------------------
//                              PDD_WaveProc
// -----------------------------------------------------------------------------
MMRESULT
PDD_WaveProc(
    WAPI_INOUT apidir,
    DWORD      dwCode,
    DWORD      dwParam1,
    DWORD      dwParam2
    )
{
    MMRESULT mmRet = MMSYSERR_NOERROR;

    EnterCriticalSection(&g_csPddWaveProcLock);

    switch (dwCode)
    {
        case WPDM_OPEN:
            mmRet = PddMsg_Open(apidir, (LPWAVEFORMATEX) dwParam1, (BOOL) dwParam2);
            break;

        case WPDM_CLOSE:
            mmRet = PddMsg_Close(apidir);
            break;

        case WPDM_RESTART: // WPDM_RESTART is more accurately thought of as "resume" (w.r.t. WPDM_PAUSE)
        case WPDM_START:
            mmRet = PddMsg_Start(apidir, (PWAVEHDR) dwParam1);
            break;

        case WPDM_PAUSE:
        case WPDM_STOP:
            mmRet = PddMsg_Stop(apidir);
            break;

        case WPDM_GETVOLUME:
            mmRet = PddMsg_OutGetVolume((PULONG) dwParam1);
            break;

        case WPDM_SETVOLUME:
            mmRet = PddMsg_OutSetVolume(dwParam1);
            break;

        case WPDM_GETDEVCAPS:
            mmRet = PddMsg_GetDevCaps(apidir, (PVOID) dwParam1, (UINT) dwParam2);
            break;

        case WPDM_ENDOFDATA:
        case WPDM_STANDBY:
        case WPDM_CONTINUE:
        default :
            mmRet = MMSYSERR_NOTSUPPORTED;
            break;
    }

    LeaveCriticalSection(&g_csPddWaveProcLock);

    return mmRet;
}


// -----------------------------------------------------------------------------
//                              PDD_AudioMessage
// -----------------------------------------------------------------------------
DWORD
PDD_AudioMessage(
    UINT uMsg,
    DWORD dwParam1,
    DWORD dwParam2
    )
{
    //
    // Handle any custom WAVEIN or WAVEOUT messages
    //
    return MMSYSERR_NOTSUPPORTED;
}

⌨️ 快捷键说明

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