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

📄 wavemdd.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

// -----------------------------------------------------------------------------
//
//      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//      PARTICULAR PURPOSE.
//  
// -----------------------------------------------------------------------------
//
//  Module Name:  
//  
//      wavemdd.c
//  
//  Abstract:  
//  
//  Functions:
//  
//  Notes:
//  
// -----------------------------------------------------------------------------
#include "wavemdd.h"

// WAPI_IN=0; WAPI_OUT=1
CRITICAL_SECTION v_GSICritSect[2];  // One for input, one for output
STREAM_INFO gsi[2];                 // Global Stream Info : one for input and one for output

BOOL    g_bDriverOpened      = FALSE;
BOOL    g_bDriverInitialized = FALSE;   //  whether it has been inited or not
BOOL    g_fInitSco           = FALSE;


#ifdef DEBUG
DBGPARAM dpCurSettings = 
{
    TEXT("BTAUDIODRV"), 
 {
  TEXT("Test"),
  TEXT("Params"),
  TEXT("Verbose"),  
  TEXT("Interrupt"),
  TEXT("WODM"),
  TEXT("WIDM"),
  TEXT("PDD"),
  TEXT("MDD"),
  TEXT("Regs"),
  TEXT("Misc"),  
  TEXT("Init"),
  TEXT("IOcontrol"),
  TEXT("Alloc"),  
  TEXT("Function"),  
  TEXT("Warning"),
  TEXT("Error") 
 },
 
    0x0000C000
};
#endif


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
BOOL WINAPI
DllEntry (
    HANDLE  hinstDLL,
    DWORD   Op,
    LPVOID  lpvReserved
    )
{
    switch (Op) 
    {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER((HINSTANCE)hinstDLL);
            DisableThreadLibraryCalls((HMODULE) hinstDLL);
            BSS_VERBOSE2(TEXT("DLL_PROCESS_ATTACH: ProcessId=%#x hinstDLL=%#x"), GetCurrentProcessId(), hinstDLL);
            break;

        case DLL_PROCESS_DETACH:
        case DLL_THREAD_DETACH:
        case DLL_THREAD_ATTACH:
        default:
            break;
    }
    return TRUE;
}


// -----------------------------------------------------------------------------
//                      RemoveCompleteBlocks
// -----------------------------------------------------------------------------
VOID
RemoveCompleteBlocks(
    WAPI_INOUT apidir
    )
{
	PREFAST_ASSERT(apidir < 2);
	
    UINT uMsg = ((apidir == WAPI_OUT) ? MM_WOM_DONE : MM_WIM_DATA);
    DRVCALLBACK* pfnCallback = gsi[apidir].pfnCallback;
    HANDLE hWave = gsi[apidir].hWave;
    PWAVEHDR pwh = gsi[apidir].pwh;

    while (gsi[apidir].pwh != NULL) {

        if (IS_BUFFER_DONE(gsi[apidir].pwh))  {

            pwh = gsi[apidir].pwh;

            if (IS_BUFFER_INLOOP(pwh)) {
                //
                // This buffer is in a loop.
                //
                if (IS_BUFFER_BEGINLOOP(pwh)) {
                    if (pwh->dwLoops == 1) {
                        PWAVEHDR pwh_temp = pwh;
                        while (pwh_temp != NULL) {
                            MARK_BUFFER_NOT_INLOOP(pwh_temp);
                            pwh_temp = pwh_temp->lpNext;
                        }   
                    } else {
                        if (pwh->dwLoops != INFINITE)
                            pwh->dwLoops--;
                    }

                }

            }


            if (!IS_BUFFER_INLOOP(pwh)) {
                //
                // Only remove a block if it's not in a loop.
                //
                //DEBUGMSG(1, (_T("=== BT Audio Driver: Sending callback into mixer: Tick:%u\n"), GetTickCount()));
                
                BSS_INTMSG("Block Complete... Sending callback");

                gsi[apidir].dwBytePosition += gsi[apidir].pwh->dwBytesRecorded;
                gsi[apidir].pwh = gsi[apidir].pwh->lpNext;
                gsi[apidir].pwhReal = gsi[apidir].pwh;
                MARK_BUFFER_DEQUEUED(pwh);
                //
                // Make the callback function call to the Wave API Manager
                //
                if (pfnCallback) {
                    pfnCallback(hWave, uMsg, gsi[apidir].dwInstance, (DWORD) pwh, 0);
                }

            } else {
                //
                // If this buffer is in a loop, then just advance to the next block.
                //
                if (IS_BUFFER_ENDLOOP(pwh) || pwh->lpNext == NULL) {
                    gsi[apidir].pwh = gsi[apidir].pwhReal;   // go the beginning.
                } else {
                    gsi[apidir].dwBytePosition += gsi[apidir].pwh->dwBytesRecorded;
                    gsi[apidir].pwh = gsi[apidir].pwh->lpNext;
                }
                //
                // Since we're not actually removing anything, we don't want to loop.
                //
                MARK_BUFFER_NOT_DONE(pwh);
                MARK_BUFFER_EMPTY(pwh);
                break;
            }


        } else {
            //
            // Only remove from the front of the list, but as many as are done.
            //
            break;  // If the first one's not DONE, then break the loop.
        }

    }   
}



// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
DWORD
GetBytePosition(
    WAPI_INOUT apidir
    )
{
    DWORD dwBytePositionTotal;    

    LOCK_GSI(apidir);
    if (gsi[apidir].pwh != NULL)
        dwBytePositionTotal = gsi[apidir].dwBytePosition + 
                              gsi[apidir].pwh->dwBytesRecorded;
    else
        dwBytePositionTotal = gsi[apidir].dwBytePosition;
    UNLOCK_GSI(apidir);

    return(dwBytePositionTotal);
}



// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
MarkAllAsDone(
    WAPI_INOUT apidir
    )
{
    PWAVEHDR pwh_temp = gsi[apidir].pwh;

    while (pwh_temp != NULL) {
        MARK_BUFFER_DONE(pwh_temp);
        pwh_temp = pwh_temp->lpNext;
    }   
}


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
MarkAllAsNotInLoop(
    WAPI_INOUT apidir
    )
{
    PWAVEHDR pwh_temp = gsi[apidir].pwh;

    while (pwh_temp != NULL) {
        MARK_BUFFER_NOT_INLOOP(pwh_temp);
        pwh_temp = pwh_temp->lpNext;
    }   
}


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
MarkAllAsFull(
    WAPI_INOUT apidir
    )
{
    PWAVEHDR pwh_temp = gsi[apidir].pwh;

    while (pwh_temp != NULL) {
        MARK_BUFFER_FULL(pwh_temp);
        pwh_temp = pwh_temp->lpNext;
    }   
}


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
MarkFullAsDone(
    WAPI_INOUT apidir
    )
{
    PWAVEHDR pwh_temp = gsi[apidir].pwh;

    while (pwh_temp != NULL) {
        if (IS_BUFFER_FULL(pwh_temp))  {
            MARK_BUFFER_DONE(pwh_temp);
        }
        pwh_temp = pwh_temp->lpNext;
    }   
}



// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
InitGSI(
    WAPI_INOUT apidir
    )
{
    BSS_FUNC_WMDD("+InitGSI");

    gsi[apidir].pwh = NULL;
    gsi[apidir].pwhReal = NULL;
    gsi[apidir].bInLoop = FALSE;
    gsi[apidir].bStarted = FALSE;
    gsi[apidir].bPaused = FALSE;
    gsi[apidir].bInMiddle = FALSE;
    gsi[apidir].pfnCallback = NULL;
    gsi[apidir].dwInstance = 0;
    gsi[apidir].dwOpenFlags = 0;
    gsi[apidir].pwfx = NULL;
    gsi[apidir].hWave = INVALID_HANDLE_VALUE;

    BSS_FUNC_WMDD("-InitGSI");
}


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
WMDD_PowerHandler(
   BOOL power_down
   )
{
    PDD_AudioPowerHandler(power_down);
}



// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
BOOL
WMDD_Deinit(
    DWORD dwData
    )
{
    BSS_FUNCTION1 ("WAV_Deinit(0x%X)\r\n", dwData);

    PDD_AudioDeinitialize();

    DeleteCriticalSection(&(v_GSICritSect[WAPI_IN]));
    DeleteCriticalSection(&(v_GSICritSect[WAPI_OUT]));

    g_bDriverInitialized = FALSE;

    return TRUE;
}




// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
DWORD
WMDD_Init(
    DWORD Index
    )
{
    if(g_bDriverInitialized)
        return  10L;    //  already inited,

    BSS_FUNC_WMDD("+WMDD_Init");
    BSS_HEXPARAM(Index);

    InitializeCriticalSection(&(v_GSICritSect[WAPI_IN]));
    InitializeCriticalSection(&(v_GSICritSect[WAPI_OUT]));

    //  init the hardware first
    if (PDD_AudioInitialize(Index) != TRUE) {
        BSS_ERRMSG("PDD_AudioInitialize() FAILED");
        goto InitFail;
    }

    BSS_FUNC_WMDD("-WMDD_Init (SUCCESS)");

    g_bDriverInitialized = TRUE; //  set it
    g_bDriverOpened = FALSE;

    // Return Non-Zero for success, will be passed to Deinit and Open
    return 1;

InitFail:
    BSS_FUNC_WMDD("-WMDD_Init (FAILURE)");

    WMDD_Deinit(0);
    return  0L;
}

⌨️ 快捷键说明

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