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

📄 wavemdd.c

📁 嵌入式操作系统wince5.0下的声卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    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;

    FUNC_WMDD("-InitGSI");
}



// -----------------------------------------------------------------------------
//                      WMDD_InterruptThread
// -----------------------------------------------------------------------------
//  This is the interrupt thread which waits on an audio interrupt event.
// -----------------------------------------------------------------------------
ULONG 
WMDD_InterruptThread(
   VOID
   )
{
    AUDIO_STATE state;
    DWORD dwAccessKey;

    FUNC_WMDD("+WMDD_InterruptThread");

    while (TRUE)  {
        WaitForSingleObject(hAudioInterrupt, INFINITE);

        if (fPowerUp) {
            INTMSG("Audio MDD is recovering from Power On");
            fPowerUp = FALSE;
            InterruptDone(gIntrAudio);

            LOCK_GSI(WAPI_OUT);
            LOCK_GSI(WAPI_IN);

            dwAccessKey=GetCurrentPermissions();
            SetProcPermissions((ULONG) -1);

            MarkAllAsFull(WAPI_IN);
            MarkAllAsFull(WAPI_OUT);
            MarkAllAsNotInLoop(WAPI_OUT);
            MarkFullAsDone(WAPI_IN);
            MarkFullAsDone(WAPI_OUT);
            RemoveCompleteBlocks(WAPI_OUT);
            RemoveCompleteBlocks(WAPI_IN);

            SetProcPermissions(dwAccessKey);

            gsi[WAPI_OUT].bStarted=FALSE;

            UNLOCK_GSI(WAPI_IN);
            UNLOCK_GSI(WAPI_OUT);

            //
            // Go back to waiting for real interrupts
            //
            continue;
        }

        INTMSG("INT!");
        state = PDD_AudioGetInterruptType();
        InterruptDone(gIntrAudio);

        //  before we try to access the gsi[apidir].pwh, need to set access key
        dwAccessKey=GetCurrentPermissions();
        SetProcPermissions((ULONG) -1); //  access everybody

        //
        // Check for output state...
        //
        switch (state & AUDIO_STATE_OUT_MASK) {

            case AUDIO_STATE_OUT_UNDERFLOW:
                INTMSG("Audio Underflowed!");
                LOCK_GSI(WAPI_OUT);
                MarkFullAsDone(WAPI_OUT);
                RemoveCompleteBlocks(WAPI_OUT);
                if (gsi[WAPI_OUT].pwh != NULL)
                    PDD_WaveProc(WAPI_OUT, WPDM_START, (DWORD) gsi[WAPI_OUT].pwh, 0);
                UNLOCK_GSI(WAPI_OUT);
                break;

            case AUDIO_STATE_OUT_PLAYING:
               
                INTMSG("Audio Playing");

                LOCK_GSI(WAPI_OUT);
                MarkFullAsDone(WAPI_OUT);
                RemoveCompleteBlocks(WAPI_OUT);
                //
                // Send more data if there is more or else stop the audio.
                //
                if (gsi[WAPI_OUT].pwh != NULL) {
                    PDD_WaveProc(WAPI_OUT, WPDM_CONTINUE, (DWORD) gsi[WAPI_OUT].pwh, 0);
                } else {
                    INTMSG("No more data. List is NULL. Stopping audio.");
                    gsi[WAPI_OUT].bStarted=FALSE;
                    PDD_WaveProc(WAPI_OUT, WPDM_ENDOFDATA, 0, 0);
                }

                UNLOCK_GSI(WAPI_OUT);
                break;

            case AUDIO_STATE_OUT_STOPPED:
                INTMSG("Audio Stopped!");
                LOCK_GSI(WAPI_OUT);
                PDD_WaveProc(WAPI_OUT, WPDM_STANDBY, 0, 0);
                gsi[WAPI_OUT].bStarted=FALSE;
                UNLOCK_GSI(WAPI_OUT);
                INTMSG("End of Play");
                break;

            case AUDIO_STATE_IGNORE:
                INTMSG("No output state change. Do nothing.");
                break;

            default:
                ERRMSG("Invalid output interrupt type!");
                break;
        }

        //
        // Check for input state...
        //
        switch (state & AUDIO_STATE_IN_MASK) {

            case AUDIO_STATE_IN_OVERFLOW:
                INTMSG("Audio Overflowed!");
                LOCK_GSI(WAPI_IN);
                MarkFullAsDone(WAPI_IN);
                RemoveCompleteBlocks(WAPI_IN);
                PDD_WaveProc(WAPI_IN, WPDM_START, (DWORD) gsi[WAPI_IN].pwh, 0);

                UNLOCK_GSI(WAPI_IN);
                break;

            case AUDIO_STATE_IN_RECORDING:
               
                INTMSG("Audio Recording");
                LOCK_GSI(WAPI_IN);
                MarkFullAsDone(WAPI_IN);
                RemoveCompleteBlocks(WAPI_IN);
                //
                // Send more data if there is more or else stop the audio.
                //
                PDD_WaveProc(WAPI_IN, WPDM_CONTINUE, (DWORD) gsi[WAPI_IN].pwh, 0);

                UNLOCK_GSI(WAPI_IN);
                break;

            case AUDIO_STATE_IN_STOPPED:
                INTMSG("Audio Stopped!");

                LOCK_GSI(WAPI_IN);
                MarkFullAsDone(WAPI_IN);
                RemoveCompleteBlocks(WAPI_IN);

                PDD_WaveProc(WAPI_IN, WPDM_STANDBY, 0, 0);
                gsi[WAPI_IN].bStarted=FALSE;
                UNLOCK_GSI(WAPI_IN);

                INTMSG("End of Play");
                break;


            case AUDIO_STATE_IGNORE:
                INTMSG("No input state change. Do nothing.");
                break;

            default:
                ERRMSG("Invalid input interrupt type!");
                break;

        }  // switch

        //  change permission back
        SetProcPermissions(dwAccessKey);

    }  // while(TRUE)

   return TRUE;
}



// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
WMDD_PowerHandler(
   BOOL power_down
   )
{
    if (!power_down) {
        fPowerUp = TRUE;
        SetInterruptEvent(gIntrAudio);
    }

    PDD_AudioPowerHandler(power_down);
}



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

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

    if (hAudioInterrupt) {
        CloseHandle(hAudioInterrupt);
        hAudioInterrupt = NULL;
    }

    g_bDriverInitialized = FALSE;

    return TRUE;
}




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

    FUNC_WMDD("+WMDD_Init");
    DECPARAM(Index);

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

    if(!(hAudioInterrupt = CreateEvent( NULL, FALSE, FALSE,NULL))) {
        ERRMSG("CreateEvent() FAILED");
        goto InitFail;
    }

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

    if (! InterruptInitialize(gIntrAudio, hAudioInterrupt, NULL, 0)) {
		DEBUGMSG(ZONE_ERROR, (TEXT("WMDD_Init - InterruptInitialize(%d,%08x) Failed\r\n"), gIntrAudio, hAudioInterrupt));
        goto InitFail;
    }

    hAudioInterruptThread  = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
                                          0,
                                          (LPTHREAD_START_ROUTINE)WMDD_InterruptThread,
                                          NULL,
                                          0,
                                          NULL);
    if (!hAudioInterruptThread) {
    	InterruptDisable(gIntrAudio);
        ERRMSG("hAudioInterruptThread Create FAILED");
        goto InitFail;
    }

    // 
    // Bump up the priority since the interrupt must be serviced
    // immediately. Both threads do a WaitForSingleObject when not
    // processing so changing priority does not affect overall 
    // performance. It merely gives the audio prompt response.
    //
    CeSetThreadPriority(hAudioInterruptThread, GetInterruptThreadPriority((LPWSTR)Index));
    
    InterruptDone(gIntrAudio);

    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:
    FUNC_WMDD("-WMDD_Init (FAILURE)");

    WMDD_Deinit(0);
    return  0L;
}

⌨️ 快捷键说明

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