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

📄 wavepdd.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 5 页
字号:

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveInStop
//
// Purpose: stop recording immediately
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveInStop(
    PWAVEHDR pwh
    )
{
    FUNC_WPDD("+PDD_WaveInStop");

    v_fMoreData[WAPI_IN] = FALSE;

    StopDmac(gInputSrc);

    AudioInMute(TRUE);

    FUNC_WPDD("-PDD_WaveInStop");

}

//------------------------------------------------------------------------------------------------------------
// Function: PowerDownUnit
//
// Purpose: power up or power down a dac, adc, or other devices
//-------------------------------------------------------------------------------------------------------------
void PowerDownUnit(unsigned short int Unit,BOOL ShutDown)
{

    //TODO Do we need to wait some time before powering on or off the unit?
    unsigned short int PowerDownCtrlStat=0;

    if( !ShadowReadAC97( POWERDOWN_CTRL_STAT, &PowerDownCtrlStat, DEV_AUDIO)  )  // Enable Variable Rate Audio
            DEBUGMSG(ZONE_ERROR, (TEXT( "-- read of PwrDnCtrl failed \r\n")   ) );

    if (ShutDown)
        PowerDownCtrlStat |= Unit;
    else
        PowerDownCtrlStat &= ~Unit;

    if( !ShadowWriteAC97( POWERDOWN_CTRL_STAT, PowerDownCtrlStat , DEV_AUDIO)  )  // Enable Variable Rate Audio
            DEBUGMSG(ZONE_ERROR, (TEXT( "-- Bad VRA Value \r\n")   ) );

}



//------------------------------------------------------------------------------------------------------------
// Function: private_WaveStandby
//
// Purpose: instruct the audio PDD to put the audio circuitry in standby mode.
//    According to the documentation this function "This message should turn off as much of the audio circuit
//    as possible. When this message is called again, the audio circuitry should be turned on as quickly as
//    possibly [sic]. This message is sent between playback of sounds to minimize audio circuit power drain.
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveStandby(
    WAPI_INOUT apidir
    )
{
    static BOOL PowerDownIn=TRUE;
    static BOOL PowerDownOut=TRUE;


    //TODO: this function doesn't seem to get called under PB 3.0
    switch(apidir)
    {
        case WAPI_IN:
            DEBUGMSG(ZONE_TEST,(TEXT("wavestandby PowerDownIn: %x WAPI_INOUT: %x\r\n"),PowerDownIn,apidir));
            PowerDownUnit(PWR_PR0_ADC,PowerDownIn);  //turn
            PowerDownIn=!PowerDownIn;
            break;

        case WAPI_OUT:
            DEBUGMSG(ZONE_TEST,(TEXT("wavestandby PowerDownOut: %x WAPI_INOUT: %x\r\n"),PowerDownOut,apidir));
            PowerDownUnit(PWR_PR1_DAC,PowerDownOut);  //turn
            PowerDownOut=!PowerDownOut;
            break;

        default:
            DEBUGMSG(ZONE_TEST,(TEXT("bad param in wavestandby\r\n")));
            DEBUGCHK(FALSE);
    }

}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveGetDevCaps
//
// Purpose: return the capabilities of the audio hardware
//-------------------------------------------------------------------------------------------------------------
MMRESULT
private_WaveGetDevCaps(
    WAPI_INOUT apidir,
    PVOID pCaps,
    UINT  wSize
    )
{


    PWAVEINCAPS pwic = pCaps;
    PWAVEOUTCAPS pwoc = pCaps;

    MMRESULT mmRet = MMSYSERR_NOERROR;

    FUNC_WPDD("+PDD_WaveGetDevCaps");

   if (pCaps == NULL)  {
        //
        // If pCaps == NULL, we are requesting if the driver PDD is capable of
        // this mode at all. In other words, if APIDIR == WAPI_IN,  we return
        // no error if input is supported, and MMSYSERR_NOTSUPPORTED otherwise.
        // Since UCB1400 has both, we return MMSYSERR_NOERROR regardless.
        //
        if( WAPI_IN == apidir)
            return( MMSYSERR_NOERROR );
        else // ( WAPI_OUT == apidir)
            return( MMSYSERR_NOERROR );
    }
    //
    // Fill in the DevCaps here.
    //
    if (apidir == WAPI_OUT)
    {
        DEBUGMSG(ZONE_VERBOSE, (TEXT("API_OUT\r\n"  )) );

        pwoc->wMid = MM_MICROSOFT;  //TODO: this says microsoft wrote this driver, change to intel
        pwoc->wPid = (apidir == WAPI_OUT ? 24 : 23);  // generic in or out...
        pwoc->vDriverVersion = 0x0001;
        wsprintf (pwoc->szPname, TEXT("AC '97  Stereo (%hs)"), __DATE__);
        pwoc->dwFormats =   WAVE_FORMAT_1M08 |
                            WAVE_FORMAT_1M16 |
                            WAVE_FORMAT_1S08 |
                            WAVE_FORMAT_1S16 |
                            WAVE_FORMAT_2M08 |
                            WAVE_FORMAT_2M16 |
                            WAVE_FORMAT_2S08 |
                            WAVE_FORMAT_2S16 |
                            WAVE_FORMAT_4M08 |
                            WAVE_FORMAT_4M16 |
                            WAVE_FORMAT_4S08 |
                            WAVE_FORMAT_4S16;


        pwoc->wChannels = 2;

        //pwoc->dwSupport = WAVECAPS_VOLUME | WAVECAPS_SYNC  ;

    }
    else
    {
        DEBUGMSG(ZONE_VERBOSE, (TEXT("API_IN\r\n"  )) );
        pwic->wMid = MM_MICROSOFT;  //TODO: this says microsoft wrote this driver, change to intel
        pwic->wPid = (apidir == WAPI_OUT ? 24 : 23);  // generic in or out...
        pwic->vDriverVersion = 0x0001;
        wsprintf (pwoc->szPname, TEXT("AC '97  Stereo (%hs)"), __DATE__);
        pwic->dwFormats =   WAVE_FORMAT_1M08 |
                            WAVE_FORMAT_1M16 |
                            WAVE_FORMAT_1S08 |
                            WAVE_FORMAT_1S16 |
                            WAVE_FORMAT_2M08 |
                            WAVE_FORMAT_2M16 |
                            WAVE_FORMAT_2S08 |
                            WAVE_FORMAT_2S16 |
                            WAVE_FORMAT_4M08 |
                            WAVE_FORMAT_4M16 |
                            WAVE_FORMAT_4S08 |
                            WAVE_FORMAT_4S16;



        pwic->wChannels = 2;

        //pwic->dwSupport = WAVECAPS_VOLUME | WAVECAPS_SYNC  ;

     }

    FUNC_WPDD("-PDD_WaveGetDevCaps");;

    return(mmRet);
}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOpen
//
// Purpose:  prepare to either send or receive audio data (based on WAPI_INOUT direction flag)
//-------------------------------------------------------------------------------------------------------------
MMRESULT
private_WaveOpen(
    WAPI_INOUT apidir,
    LPWAVEFORMATEX lpFormat,
    BOOL fQueryFormatOnly
    )
{

    MMRESULT mmRet = MMSYSERR_NOERROR;

    FUNC_VERBOSE("+PDD_WaveOpen");

    switch (CodecType)
    {
        case UCB14002A:
            if ((lpFormat->wFormatTag         != WAVE_FORMAT_PCM)  ||
               (  lpFormat->nChannels         != 1 &&
                  lpFormat->nChannels         != 2)             ||
               (  lpFormat->nSamplesPerSec    != KHZ08_000 &&
                  lpFormat->nSamplesPerSec    != KHZ11_025 &&
                  lpFormat->nSamplesPerSec    != KHZ12_000 &&
                  lpFormat->nSamplesPerSec    != KHZ22_050 &&
                  lpFormat->nSamplesPerSec    != KHZ24_000 &&
                  lpFormat->nSamplesPerSec    != KHZ32_000 &&
                  lpFormat->nSamplesPerSec    != KHZ44_100 &&
                  lpFormat->nSamplesPerSec    != KHZ48_000
                  )         ||
               (  lpFormat->wBitsPerSample    != 16 &&
                  lpFormat->wBitsPerSample    != 8))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT( "return bad format\r\n" )) );
                return WAVERR_BADFORMAT;
            }
            break;

        case UCB14001B:
        default:
            if ((lpFormat->wFormatTag         != WAVE_FORMAT_PCM)  ||
               (  lpFormat->nChannels         != 1 &&
                  lpFormat->nChannels         != 2)             ||
               (  lpFormat->nSamplesPerSec    != KHZ08_000 &&
                  lpFormat->nSamplesPerSec    != KHZ11_025 &&
                  lpFormat->nSamplesPerSec    != KHZ16_000 &&
                  lpFormat->nSamplesPerSec    != KHZ22_050 &&
                  lpFormat->nSamplesPerSec    != KHZ32_000 &&
                  lpFormat->nSamplesPerSec    != KHZ44_100 &&
                  lpFormat->nSamplesPerSec    != KHZ48_000
                  )         ||
               (  lpFormat->wBitsPerSample    != 16 &&
                  lpFormat->wBitsPerSample    != 8))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT( "return bad format\r\n " )) );
                return WAVERR_BADFORMAT;
            }
    } // end switch

    //if they only want a query format, then we can return success.
    if (fQueryFormatOnly) {
        DEBUGMSG( ZONE_VERBOSE, (TEXT( "Format Query\r\n " )) );
        return MMSYSERR_NOERROR;
    }

    if (g_fInUse[apidir]) {
        DEBUGMSG(ZONE_ERROR, (TEXT("\r\n")));
        return MMSYSERR_ALLOCATED;
    }
    if (apidir < NUM_API_DIRS) g_fInUse[apidir] = TRUE;

    //ENABLE VRA
    if( !ShadowWriteAC97( EXTENDED_AUDIO_CTRL, VRA_ENABLED_MASK , DEV_AUDIO)  )  // Enable Variable Rate Audio
        DEBUGMSG(ZONE_ERROR, (TEXT( "-- Bad VRA Value \r\n")   ) );

    //set the sample rate
    if (AC97SetSampleRate((unsigned short int)lpFormat->nSamplesPerSec,apidir) == FALSE)
    {
    DEBUGMSG( 1, (TEXT( "return bad sample rate:\r\n " )) );
    return MMSYSERR_NOTSUPPORTED;
    }



    if (apidir < NUM_API_DIRS) g_sample_size[apidir] = lpFormat->nBlockAlign;

    if (apidir == WAPI_OUT) {
        if (lpFormat->wBitsPerSample == 8) {
            if (lpFormat->nChannels == 1) {
                g_pfnFillBuffer = FillBufferM08;
            }
            else {
                g_pfnFillBuffer = FillBufferS08;
            }
        }
        else {
            if (lpFormat->nChannels == 1) {
                g_pfnFillBuffer = FillBufferM16;
            }
            else {
                g_pfnFillBuffer = FillBufferS16;
            }
        }
    }
    else {
        if (lpFormat->wBitsPerSample == 8) {
            if (lpFormat->nChannels == 1) {
                g_pfnGetBuffer = GetBufferM08;
            }
            else {
                g_pfnGetBuffer = GetBufferS08;
            }
        }
        else {
            if (lpFormat->nChannels == 1) {
                g_pfnGetBuffer = GetBufferM16;
            }
            else {
                g_pfnGetBuffer = GetBufferS16;
            }
        }
        // Support Low-latency Capture
        // Adjust the effective DMA buffer size, based on the requested sample rate.
        // The idea is that we want our DMA capture buffers to represent a fixed amount of time,
        // regardless of the sample rate.
        // This means that if the application buffers are small (as is the case with VoIP or DirectSoundCapture)
        // then we still can return the buffer very soon after we have enough captured data to fill it.
        // The way this used to work (fixed-size capture buffers) meant that at low sample rates
        // we would wait for hundreds of milliseconds, then turn around and discover that the application
        // had only given us 80 milliseconds of wave headers, so we would be forced to drop samples on the floor.
        g_capture_buffer_size = sizeof(DWORD) * g_capture_latency * lpFormat->nSamplesPerSec / 1000;
        if (g_capture_buffer_size > g_dma_buffer_size) {
            g_capture_buffer_size = g_dma_buffer_size;
        }
        v_pAudioRcvA_Virtual->dcmd = (v_pAudioRcvA_Virtual->dcmd & ~0x1fff) | g_capture_buffer_size;
        v_pAudioRcvB_Virtual->dcmd = (v_pAudioRcvB_Virtual->dcmd & ~0x1fff) | g_capture_buffer_size;

    }

    ResetAC97Controller(); // this flushes the fifos and freezes AC-Link - workaround for B-Stepping problem.

    FUNC_VERBOSE("-PDD_WaveOpen");

    return MMSYSERR_NOERROR;
}


//------------------------------------------------------------------------------------------------------------
// Function: PDD_WaveProc
//
// Purpose: process WPDM_xxx messages from the MDD.  This is the main message handler for the PDD.
//-------------------------------------------------------------------------------------------------------------
MMRESULT
PDD_WaveProc(
    WAPI_INOUT apidir,
    DWORD      dwCode,
    DWORD      dwParam1,
    DWORD      dwParam2
    )
{
    MMRESULT mmRet = MMSYSERR_NOERROR;
    DEBUGMSG( ZONE_VERBOSE, (TEXT( "PDD_WaveProc: " )) );

    switch (dwCode) {
        case WPDM_CLOSE:
            if (apidir == WAPI_IN && g_fInUse[apidir]) {
                // if app never send WODM_RESET, the capture DMA is still running. Stop it now.
                private_WaveInStop(NULL);
            }
            if (apidir < NUM_API_DIRS) g_fInUse[apidir] = FALSE;
            DEBUGMSG( ZONE_VERBOSE, (TEXT( "....close %s\r\n" ),(apidir == WAPI_IN)?"i n ":"o u t ") );
            break;

        case WPDM_CONTINUE:
            DEBUGMSG( ZONE_VERBOSE, (TEXT( "....continue %s\r\n" ),(apidir == WAPI_IN)?"i n ":"o u t ") );
            if (apidir == WAPI_IN)
                private_WaveInContinue((PWAVEHDR) dwParam1);
            else
                private_WaveOutContinue((PWAVEHDR) dwParam1);
            break;

        case WPDM_GETDEVCAPS:
        DEBUGMSG( ZONE_VERBOSE, (TEXT( "....getdevcaps\r\n" )) );
            mmRet = private_WaveGetDevCaps(apidir, (PVOID) dwParam1, (UINT) dwParam2);
            break;

        case WPDM_OPEN:
        DEBUGMSG( ZONE_VERBOSE, (TEXT( "....open %s\r\n" ),(apidir == WAPI_IN)?"i n ":"o u t ") );

            mmRet = private_WaveOpe

⌨️ 快捷键说明

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