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

📄 pa_win_wmme.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
    }#endiferror:    return result;}/*************************************************************************/PaError PaHost_StopEngine( internalPortAudioStream *internalStream, int abort ){    int timeOut;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );    if( wmmeStreamData == NULL ) return paNoError;    /* Tell background thread to stop generating more data and to let current data play out. */    internalStream->past_StopSoon = 1;    /* If aborting, tell background thread to stop NOW! */    if( abort ) internalStream->past_StopNow = 1;    /* Calculate timeOut longer than longest time it could take to play all buffers. */    timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( internalStream ) / internalStream->past_SampleRate);    if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;#if PA_USE_TIMER_CALLBACK    if( (internalStream->past_OutputDeviceID != paNoDevice) &&            internalStream->past_IsActive &&            (wmmeStreamData->timerID != 0) )    {        /* Wait for IsActive to drop. */        while( (internalStream->past_IsActive) && (timeOut > 0) )        {            Sleep(10);            timeOut -= 10;        }        timeKillEvent( wmmeStreamData->timerID );  /* Stop callback timer. */        wmmeStreamData->timerID = 0;    }#else /* PA_USE_TIMER_CALLBACK */#if PA_TRACE_START_STOP    AddTraceMessage( "PaHost_StopEngine: thread ", (int) wmmeStreamData->engineThread );#endif    if( (internalStream->past_OutputDeviceID != paNoDevice) &&            (internalStream->past_IsActive) &&            (wmmeStreamData->engineThread != NULL) )    {        DWORD got;        /* Tell background thread to stop generating more data and to let current data play out. */        DBUG(("PaHost_StopEngine: waiting for background thread.\n"));        got = WaitForSingleObject( wmmeStreamData->engineThread, timeOut );        if( got == WAIT_TIMEOUT )        {            ERR_RPT(("PaHost_StopEngine: timed out while waiting for background thread to finish.\n"));            return paTimedOut;        }        CloseHandle( wmmeStreamData->engineThread );        wmmeStreamData->engineThread = NULL;    }#endif /* PA_USE_TIMER_CALLBACK */    internalStream->past_IsActive = 0;    return paNoError;}/*************************************************************************/PaError PaHost_StopInput( internalPortAudioStream *stream, int abort ){    MMRESULT mmresult;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );    if( wmmeStreamData == NULL ) return paNoError; /* FIXME: why return paNoError? */    (void) abort; /* unused parameter */    if( wmmeStreamData->hWaveIn != NULL )    {        mmresult = waveInReset( wmmeStreamData->hWaveIn );        if( mmresult != MMSYSERR_NOERROR )        {            sPaHostError = mmresult;            return paHostError;        }    }    return paNoError;}/*************************************************************************/PaError PaHost_StopOutput( internalPortAudioStream *internalStream, int abort ){    MMRESULT mmresult;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );    if( wmmeStreamData == NULL ) return paNoError;    /* FIXME: why return paNoError? */    (void) abort;   /* unused parameter */#if PA_TRACE_START_STOP    AddTraceMessage( "PaHost_StopOutput: hWaveOut ", (int) wmmeStreamData->hWaveOut );#endif    if( wmmeStreamData->hWaveOut != NULL )    {        mmresult = waveOutReset( wmmeStreamData->hWaveOut );        if( mmresult != MMSYSERR_NOERROR )        {            sPaHostError = mmresult;            return paHostError;        }    }    return paNoError;}/*******************************************************************/PaError PaHost_CloseStream( internalPortAudioStream *stream ){    int i;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );    if( stream == NULL ) return paBadStreamPtr;    if( wmmeStreamData == NULL ) return paNoError;   /* FIXME: why return no error? */#if PA_TRACE_START_STOP    AddTraceMessage( "PaHost_CloseStream: hWaveOut ", (int) wmmeStreamData->hWaveOut );#endif    /* Free data and device for output. */    if( wmmeStreamData->hWaveOut )    {        if( wmmeStreamData->outputBuffers )        {            for( i=0; i<wmmeStreamData->numHostBuffers; i++ )            {                waveOutUnprepareHeader( wmmeStreamData->hWaveOut, &wmmeStreamData->outputBuffers[i], sizeof(WAVEHDR) );                PaHost_FreeTrackedMemory( wmmeStreamData->outputBuffers[i].lpData ); /* MEM */            }            PaHost_FreeTrackedMemory( wmmeStreamData->outputBuffers ); /* MEM */        }        waveOutClose( wmmeStreamData->hWaveOut );    }    /* Free data and device for input. */    if( wmmeStreamData->hWaveIn )    {        if( wmmeStreamData->inputBuffers )        {            for( i=0; i<wmmeStreamData->numHostBuffers; i++ )            {                waveInUnprepareHeader( wmmeStreamData->hWaveIn, &wmmeStreamData->inputBuffers[i], sizeof(WAVEHDR) );                PaHost_FreeTrackedMemory( wmmeStreamData->inputBuffers[i].lpData ); /* MEM */            }            PaHost_FreeTrackedMemory( wmmeStreamData->inputBuffers ); /* MEM */        }        waveInClose( wmmeStreamData->hWaveIn );    }#if (PA_USE_TIMER_CALLBACK == 0)    if( wmmeStreamData->abortEventInited ) CloseHandle( wmmeStreamData->abortEvent );    if( wmmeStreamData->bufferEventInited ) CloseHandle( wmmeStreamData->bufferEvent );#endif    if( wmmeStreamData->streamLockInited )        DeleteCriticalSection( &wmmeStreamData->streamLock );    PaHost_FreeWMMEStreamData( stream );    return paNoError;}/************************************************************************* * Determine minimum number of buffers required for this host based * on minimum latency. Latency can be optionally set by user by setting * an environment variable. For example, to set latency to 200 msec, put: * *    set PA_MIN_LATENCY_MSEC=200 * * in the AUTOEXEC.BAT file and reboot. * If the environment variable is not set, then the latency will be determined * based on the OS. Windows NT has higher latency than Win95. */#define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ){    char      envbuf[PA_ENV_BUF_SIZE];    DWORD     hresult;    int       minLatencyMsec = 0;    double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;    int       minBuffers;    /* Let user determine minimal latency by setting environment variable. */    hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )    {        minLatencyMsec = atoi( envbuf );   /* REVIEW: will we crash if the environment variable contains some nasty value? */    }    else    {        /* Set minimal latency based on whether NT or other OS.         * NT has higher latency.         */        OSVERSIONINFO osvi;		osvi.dwOSVersionInfoSize = sizeof( osvi );		GetVersionEx( &osvi );        DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));        DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));        DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));        /* Check for NT */		if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )		{			minLatencyMsec = PA_WIN_NT_LATENCY;		}		else if(osvi.dwMajorVersion >= 5)		{			minLatencyMsec = PA_WIN_WDM_LATENCY;		}		else		{			minLatencyMsec = PA_WIN_9X_LATENCY;		}#if PA_USE_HIGH_LATENCY        PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));#endif    }    DBUG(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));    minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));    if( minBuffers < 2 ) minBuffers = 2;    return minBuffers;}/************************************************************************* * Cleanup device info. */PaError PaHost_Term( void ){    int i;    if( sNumDevices > 0 )    {        if( sDevicePtrs != NULL )        {            for( i=0; i<sNumDevices; i++ )            {                if( sDevicePtrs[i] != NULL )                {                    PaHost_FreeTrackedMemory( (char*)sDevicePtrs[i]->name ); /* MEM */                    PaHost_FreeTrackedMemory( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */                    PaHost_FreeTrackedMemory( sDevicePtrs[i] ); /* MEM */                }            }            PaHost_FreeTrackedMemory( sDevicePtrs ); /* MEM */            sDevicePtrs = NULL;        }        sNumDevices = 0;    }#if PA_TRACK_MEMORY    PRINT(("PaHost_Term: sNumAllocations = %d\n", sNumAllocations ));#endif    return paNoError;}/*************************************************************************/void Pa_Sleep( long msec ){    Sleep( msec );}/*************************************************************************FIXME: the following memory allocation routines should not be declared here * Allocate memory that can be accessed in real-time. * This may need to be held in physical memory so that it is not * paged to virtual memory. * This call MUST be balanced with a call to PaHost_FreeFastMemory(). * Memory will be set to zero. */void *PaHost_AllocateFastMemory( long numBytes ){    return PaHost_AllocateTrackedMemory( numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */}/************************************************************************* * Free memory that could be accessed in real-time. * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). */void PaHost_FreeFastMemory( void *addr, long numBytes ){    (void) numBytes; /* unused parameter */        PaHost_FreeTrackedMemory( addr ); /* MEM */}/************************************************************************* * Track memory allocations to avoid leaks. */static void *PaHost_AllocateTrackedMemory( long numBytes ){    void *result = GlobalAlloc( GPTR, numBytes ); /* MEM */#if PA_TRACK_MEMORY    if( result != NULL ) sNumAllocations += 1;#endif    return result;}static void PaHost_FreeTrackedMemory( void *addr ){    if( addr != NULL )    {        GlobalFree( addr ); /* MEM */#if PA_TRACK_MEMORY        sNumAllocations -= 1;#endif    }}/***********************************************************************/PaError PaHost_StreamActive( internalPortAudioStream *internalStream ){    if( internalStream == NULL ) return paBadStreamPtr;    return (PaError) internalStream->past_IsActive;}/************************************************************************* * This must be called periodically because mmtime.u.sample * is a DWORD and can wrap and lose sync after a few hours. */static PaError PaHost_UpdateStreamTime( PaWMMEStreamData *wmmeStreamData ){    MMRESULT  mmresult;    MMTIME    mmtime;    const int shift = 6;    mmtime.wType = TIME_SAMPLES;    if( wmmeStreamData->hWaveOut != NULL )    {        mmresult = waveOutGetPosition( wmmeStreamData->hWaveOut, &mmtime, sizeof(mmtime) );    }    else    {        mmresult = waveInGetPosition( wmmeStreamData->hWaveIn, &mmtime, sizeof(mmtime) );    }        if( mmresult != MMSYSERR_NOERROR )    {        sPaHostError = mmresult;        return paHostError;    }        /* This data has two variables and is shared by foreground and background.     * So we need to make it thread safe. */    EnterCriticalSection( &wmmeStreamData->streamLock );// The casting and shifting in computing frames played is// to deal with wrap-around. 

⌨️ 快捷键说明

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