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

📄 wavemdd.c

📁 此代码为WCE5.0下声卡的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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>


BOOL fPowerUp;

// Global
ULONG WMDD_InterruptThread(VOID);

HANDLE hAudioInterrupt;          // Handle to Audio Interrupt event.
HANDLE hAudioInterruptThread;    // Handle to thread which waits on an audio 
                                 // interrupt event.
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;
BOOL    g_bDriverInitialized;   //  whether it has been inited or not


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
BOOL WINAPI
DllEntry (
    HANDLE  hinstDLL,
    DWORD   Op,
    LPVOID  lpvReserved
    )
{
    switch (Op) {

        case DLL_PROCESS_ATTACH :
            DEBUGREGISTER((HINSTANCE)hinstDLL);
	    DisableThreadLibraryCalls((HMODULE) hinstDLL);
            break;

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



// -----------------------------------------------------------------------------
// Function to read the interrupt thread priority from the registry.
// If it is not in the registry then a default value is returned.
// -----------------------------------------------------------------------------
static DWORD
GetInterruptThreadPriority(
	LPWSTR lpszActiveKey
	)
{
    HKEY hDevKey;
    DWORD dwValType;
    DWORD dwValLen;
    DWORD dwPrio;

    dwPrio = DEFAULT_THREAD_PRIORITY;

    hDevKey = OpenDeviceKey(lpszActiveKey);
    
    if (hDevKey) {
        dwValLen = sizeof(DWORD);
        RegQueryValueEx(
        	hDevKey,
            REGISTRY_PRIORITY_VALUE,
            NULL,
            &dwValType,
            (PUCHAR)&dwPrio,
            &dwValLen);
        RegCloseKey(hDevKey);
    }

    return dwPrio;
}



// -----------------------------------------------------------------------------
//                      RemoveCompleteBlocks
// -----------------------------------------------------------------------------
VOID
RemoveCompleteBlocks(
    WAPI_INOUT apidir
    )
{
    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.
                //
                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
                //
                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
    )
{
    FUNC_WMDD("+InitGSI");

    gsi[apidir].pwh = NULL;
    gsi[apidir].pwhReal = NULL;

⌨️ 快捷键说明

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