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

📄 pa_win_wmme.c

📁 一个任天堂掌上游戏机NDS的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

        for( i = 0; i < sNumDevices; i++ )
            sDevicePtrs[i] = NULL;  /* RDB20020417 explicitly set each ptr to NULL */
    }
    else
    {
        sDevicePtrs = NULL;
    }
    
    return paNoError;
}
/*************************************************************************/
long Pa_GetHostError()
{
    return sPaHostError;
}
/*************************************************************************/
int Pa_CountDevices()
{
    if( PaHost_IsInitialized() )
        return sNumDevices;
    else
        return 0;
}
/*************************************************************************
 * If a PaDeviceInfo structure has not already been created,
 * then allocate one and fill it in for the selected device.
 *
 * We create one extra input and one extra output device for the WAVE_MAPPER.
 * [Does anyone know how to query the default device and get its name?]
 */
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
{
#define NUM_STANDARDSAMPLINGRATES   3   /* 11025, 22050, 44100 */
    static DWORD customSamplingRates[] = { 8000, 32000, 48000, 64000, 88200, 96000 };
#define NUM_CUSTOMSAMPLINGRATES     (sizeof(customSamplingRates)/sizeof(DWORD))
#define MAX_NUMSAMPLINGRATES        (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)

    PaDeviceInfo *deviceInfo;
    double *sampleRates; /* non-const ptr */
    int i;
    char *s;

    DBUG(( "Pa_GetDeviceInfo( %d )\n", id ));
    if( id < 0 || id >= sNumDevices )
        return NULL;
    if( sDevicePtrs[ id ] != NULL )
    {
        return sDevicePtrs[ id ];
    }
    deviceInfo = (PaDeviceInfo *)PaHost_AllocateTrackedMemory( sizeof(PaDeviceInfo) ); /* MEM */
    if( deviceInfo == NULL ) return NULL;
    deviceInfo->structVersion = 1;
    deviceInfo->maxInputChannels = 0;
    deviceInfo->maxOutputChannels = 0;
    deviceInfo->numSampleRates = 0;
    sampleRates = (double*)PaHost_AllocateTrackedMemory( MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */
    deviceInfo->sampleRates = sampleRates;
    deviceInfo->nativeSampleFormats = paInt16;       /* should query for higher bit depths below */
    if( id < sNumInputDevices )
    {
        /* input device */
        int inputMmID = PaDeviceIdToWinId(id);
        WAVEINCAPS wic;
        if( waveInGetDevCaps( inputMmID, &wic, sizeof( WAVEINCAPS ) ) != MMSYSERR_NOERROR )
            goto error;

        /* Append I/O suffix to WAVE_MAPPER device. */
        if( inputMmID == WAVE_MAPPER )
        {
            s = (char *) PaHost_AllocateTrackedMemory( strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */
            strcpy( s, wic.szPname );
            strcat( s, sMapperSuffixInput );
        }
        else
        {
            s = (char *) PaHost_AllocateTrackedMemory( strlen( wic.szPname ) + 1 ); /* MEM */
            strcpy( s, wic.szPname );
        }
        deviceInfo->name = s;
        deviceInfo->maxInputChannels = wic.wChannels;
        DBUG(( "Pa_GetDeviceInfo: input %s, maxChannels = %d\n", deviceInfo->name, deviceInfo->maxInputChannels ));
        /* Sometimes a device can return a rediculously large number of channels.
         * This happened with an SBLive card on a Windows ME box.
         * If that happens, then force it to 2 channels.  PLB20010413
         */
        if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )
        {
            ERR_RPT(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", deviceInfo->maxOutputChannels ));
            deviceInfo->maxInputChannels = 2;
        }
        /* Add a sample rate to the list if we can do stereo 16 bit at that rate
         * based on the format flags. */
        if( wic.dwFormats & WAVE_FORMAT_1M16 ||wic.dwFormats & WAVE_FORMAT_1S16 )
            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;
        if( wic.dwFormats & WAVE_FORMAT_2M16 ||wic.dwFormats & WAVE_FORMAT_2S16 )
            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;
        if( wic.dwFormats & WAVE_FORMAT_4M16 ||wic.dwFormats & WAVE_FORMAT_4S16 )
            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;
        /* Add a sample rate to the list if we can do stereo 16 bit at that rate
         * based on opening the device successfully. */
        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )
        {
            WAVEFORMATEX wfx;
            wfx.wFormatTag = WAVE_FORMAT_PCM;
            wfx.nSamplesPerSec = customSamplingRates[i];
            wfx.wBitsPerSample = 16;
            wfx.cbSize = 0; /* ignored */
            wfx.nChannels = (WORD)deviceInfo->maxInputChannels;
            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);
            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));
            if( waveInOpen( NULL, inputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )
            {
                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];
            }
        }

    }
    else if( id - sNumInputDevices < sNumOutputDevices )
    {
        /* output device */
        int outputMmID = PaDeviceIdToWinId(id);
        WAVEOUTCAPS woc;
        if( waveOutGetDevCaps( outputMmID, &woc, sizeof( WAVEOUTCAPS ) ) != MMSYSERR_NOERROR )
            goto error;
        /* Append I/O suffix to WAVE_MAPPER device. */
        if( outputMmID == WAVE_MAPPER )
        {
            s = (char *) PaHost_AllocateTrackedMemory( strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) );  /* MEM */
            strcpy( s, woc.szPname );
            strcat( s, sMapperSuffixOutput );
        }
        else
        {
            s = (char *) PaHost_AllocateTrackedMemory( strlen( woc.szPname ) + 1 );  /* MEM */
            strcpy( s, woc.szPname );
        }
        deviceInfo->name = s;
        deviceInfo->maxOutputChannels = woc.wChannels;
        DBUG(( "Pa_GetDeviceInfo: output %s, maxChannels = %d\n", deviceInfo->name, deviceInfo->maxOutputChannels ));
        /* Sometimes a device can return a rediculously large number of channels.
         * This happened with an SBLive card on a Windows ME box.
         * It also happens on Win XP!
         */
        if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )
        {
#if 1
            deviceInfo->maxOutputChannels = 2;
#else
        /* If channel max is goofy, then query for max channels. PLB20020228
         * This doesn't seem to help. Disable code for now. Remove it later.
         */
            ERR_RPT(("Pa_GetDeviceInfo: Num output channels reported as %d!", deviceInfo->maxOutputChannels ));
            deviceInfo->maxOutputChannels = 0;
			/* Attempt to find the correct maximum by querying the device. */
			for( i=2; i<16; i += 2 )
			{
				WAVEFORMATEX wfx;
				wfx.wFormatTag = WAVE_FORMAT_PCM;
				wfx.nSamplesPerSec = 44100;
				wfx.wBitsPerSample = 16;
				wfx.cbSize = 0; /* ignored */
				wfx.nChannels = (WORD) i;
				wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);
				wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));
				if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )
				{
					deviceInfo->maxOutputChannels = i;
				}
				else
				{
					break;
				}
			}
#endif
            ERR_RPT((" Changed to %d.\n", deviceInfo->maxOutputChannels ));
        }

        /* Add a sample rate to the list if we can do stereo 16 bit at that rate
         * based on the format flags. */
        if( woc.dwFormats & WAVE_FORMAT_1M16 ||woc.dwFormats & WAVE_FORMAT_1S16 )
            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;
        if( woc.dwFormats & WAVE_FORMAT_2M16 ||woc.dwFormats & WAVE_FORMAT_2S16 )
            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;
        if( woc.dwFormats & WAVE_FORMAT_4M16 ||woc.dwFormats & WAVE_FORMAT_4S16 )
            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;

        /* Add a sample rate to the list if we can do stereo 16 bit at that rate
         * based on opening the device successfully. */
        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )
        {
            WAVEFORMATEX wfx;
            wfx.wFormatTag = WAVE_FORMAT_PCM;
            wfx.nSamplesPerSec = customSamplingRates[i];
            wfx.wBitsPerSample = 16;
            wfx.cbSize = 0; /* ignored */
            wfx.nChannels = (WORD)deviceInfo->maxOutputChannels;
            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);
            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));
            DBUG(( "Pa_GetDeviceInfo: waveOutOpen( ... WAVE_FORMAT_QUERY at SR = %d\n", customSamplingRates[i] ));
            if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )
            {
                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];
            }
        }
    }
    DBUG(( "Pa_GetDeviceInfo: done.\n" ));
    sDevicePtrs[ id ] = deviceInfo;
    return deviceInfo;

error:
    PaHost_FreeTrackedMemory( sampleRates ); /* MEM */
    PaHost_FreeTrackedMemory( deviceInfo ); /* MEM */

    return NULL;
}
/*************************************************************************
 * Returns recommended device ID.
 * On the PC, the recommended device can be specified by the user by
 * setting an environment variable. For example, to use device #1.
 *
 *    set PA_RECOMMENDED_OUTPUT_DEVICE=1
 *
 * The user should first determine the available device ID by using
 * the supplied application "pa_devs".
 */
#define PA_ENV_BUF_SIZE  (32)
#define PA_REC_IN_DEV_ENV_NAME  ("PA_RECOMMENDED_INPUT_DEVICE")
#define PA_REC_OUT_DEV_ENV_NAME  ("PA_RECOMMENDED_OUTPUT_DEVICE")
static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )
{
    DWORD   hresult;
    char    envbuf[PA_ENV_BUF_SIZE];
    PaDeviceID recommendedID = paNoDevice;

    /* Let user determine default device by setting environment variable. */
    hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );
    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
    {
        recommendedID = atoi( envbuf );
    }
    return recommendedID;
}
/**********************************************************************
 * Check for environment variable, else query devices and use result.
 */
PaDeviceID Pa_GetDefaultInputDeviceID( void )
{
    PaDeviceID result;

    result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );
    if( result == paNoDevice || result < 0 || result >= sNumInputDevices )
    {
        result = sDefaultInputDeviceID;
    }
    return result;
}
PaDeviceID Pa_GetDefaultOutputDeviceID( void )
{
    PaDeviceID result;

    result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );
    if( result == paNoDevice || result < sNumInputDevices || result >= sNumDevices )
    {
        result = sDefaultOutputDeviceID;
    }
    return result;
}
/**********************************************************************
 * Initialize Host dependant part of API.
 */
PaError PaHost_Init( void )
{

#if PA_TRACK_MEMORY
    PRINT(("PaHost_Init: sNumAllocations = %d\n", sNumAllocations ));
#endif

#if PA_SIMULATE_UNDERFLOW
    PRINT(("WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\n"));
#endif
   

    Pa_InitializeNumDevices();

    return Pa_AllocateDevicePtrs();
}

/**********************************************************************
 * Check WAVE buffers to see if they are done.
 * Fill any available output buffers and use any available
 * input buffers by calling user callback.
 *
 * This routine will loop until:
 *    user callback returns !=0 OR
 *    all output buffers are filled OR
 *    past->past_StopSoon is set OR
 *    an error occurs when calling WMME.
 *
 * Returns >0 when user requests a stop, <0 on error.
 *
 */
static PaError Pa_TimeSlice( internalPortAudioStream *stream )
{
    PaError           result = paNoError;
    MMRESULT          mmresult;
    char             *inBufPtr;
    char             *outBufPtr;
    int               gotInput = 0;
    int               gotOutput = 0;
    int               i;
    int               buffersProcessed = 0;
    int               done = 0;
    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;

    if( wmmeStreamData == NULL ) return paInternalError;

    stream->past_NumCallbacks += 1;
#if PA_TRACE_RUN
    AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", stream->past_NumCallbacks );
#endif

    /* JM20020118 - prevent hung thread when buffers underflow. */
    /* while( !done ) /* BAD */
    while( !done && !stream->past_StopSoon ) /* GOOD */

⌨️ 快捷键说明

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