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

📄 pa_win_wmme.c

📁 ppciaxclient softphone
💻 C
📖 第 1 页 / 共 4 页
字号:

	pa_stdout = fopen("\\Program Files\\myApp\\pa_Host_StartEngine.txt","w+t");

    past->past_StopSoon = 0;
    past->past_StopNow = 0;
	past->past_IsActive = 1;
	pahsc->pahsc_FramesPlayed = 0.0;
	pahsc->pahsc_LastPosition = 0;
#if PA_TRACE_START_STOP
	pa_len=sprintf(pa_buf,"PaHost_StartEngine: TimeSlice() returned ", result );
	pa_nbw = fwrite(pa_buf,1,pa_len,pa_stdout); fflush(pa_stdout);
#endif
#if PA_USE_TIMER_CALLBACK
/* Create timer that will wake us up so we can fill the DSound buffer. */
	bufsPerTimerCallback = pahsc->pahsc_NumHostBuffers/4;
	if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;
	if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;
	msecPerBuffer = (1000 * bufsPerTimerCallback *
		pahsc->pahsc_UserBuffersPerHostBuffer *
		past->past_FramesPerUserBuffer ) / (int) past->past_SampleRate;
	if( msecPerBuffer < 10 ) msecPerBuffer = 10;
	else if( msecPerBuffer > 100 ) msecPerBuffer = 100;
	resolution = msecPerBuffer/4;
	pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution,
	                                     (LPTIMECALLBACK) Pa_TimerCallback,
	                                     (DWORD) past, TIME_PERIODIC );
	if( pahsc->pahsc_TimerID == 0 )
	{
		result = paHostError;
		sPaHostError = GetLastError();;
    	pa_len=sprintf(pa_buf,"PaHost_StartEngine: checkpoint#1 result=%d", result );
	    pa_nbw = fwrite(pa_buf,1,pa_len,pa_stdout); fflush(pa_stdout);
		goto error;
	}
#else /* PA_USE_TIMER_CALLBACK */
	ResetEvent( pahsc->pahsc_AbortEvent );
/* Create thread that waits for audio buffers to be ready for processing. */
	pahsc->pahsc_EngineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, past, 0, &pahsc->pahsc_EngineThreadID );
	if( pahsc->pahsc_EngineThread == NULL )
	{
		result = paHostError;
		sPaHostError = GetLastError();;
		pa_len=sprintf(pa_buf,"PaHost_StartEngine: checkpoint#2 result=%d", result );
	    pa_nbw = fwrite(pa_buf,1,pa_len,pa_stdout); fflush(pa_stdout);
		goto error;
	}
#if PA_TRACE_START_STOP
	pa_len=sprintf(pa_buf,"PaHost_StartEngine: thread ", (int) pahsc->pahsc_EngineThread);
	pa_nbw = fwrite(pa_buf,1,pa_len,pa_stdout); fflush(pa_stdout);
#endif
/* I used to pass the thread which was failing. I now pass GetCurrentProcess().
** This fix could improve latency for some applications. It could also result in CPU
** starvation if the callback did too much processing.
** I also added result checks, so we might see more failures at initialization.
** Thanks to Alberto di Bene for spotting this.
*/
/*  if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) */ /* PLB20010816 */

// disable this code because it is causing a run-time termimation
//	if( !SetThreadPriority( GetCurrentProcess(), THREAD_PRIORITY_HIGHEST ) ) /* GJG20020929 */
//	{
//		result = paHostError;
//		sPaHostError = GetLastError();;
//  	pa_len=sprintf(pa_buf,"PaHost_StartEngine: checkpoint#3 result=%d", result );
//	    pa_nbw = fwrite(pa_buf,1,pa_len,pa_stdout); fflush(pa_stdout);
//		goto error;
//	}

    if( !SetThreadPriority( pahsc->pahsc_EngineThread, THREAD_PRIORITY_HIGHEST ) )
	{
		result = paHostError;
		sPaHostError = GetLastError();;
    	pa_len=sprintf(pa_buf,"PaHost_StartEngine: checkpoint#4 result=%d", result );
	    pa_nbw = fwrite(pa_buf,1,pa_len,pa_stdout); fflush(pa_stdout);
		goto error;
	}

#endif
error:
    fclose(pa_stdout);
	return result;
}
/*************************************************************************/
PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
{
	int timeOut;
	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return paNoError;
/* Tell background thread to stop generating more data and to let current data play out. */
	past->past_StopSoon = 1;
/* If aborting, tell background thread to stop NOW! */
	if( abort ) past->past_StopNow = 1;
/* Calculate timeOut longer than longest time it could take to play all buffers. */
	timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);
	if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;
#if PA_USE_TIMER_CALLBACK
	if( (past->past_OutputDeviceID != paNoDevice) &&
		past->past_IsActive &&
		(pahsc->pahsc_TimerID != 0) )
	{
	/* Wait for IsActive to drop. */
		while( (past->past_IsActive) &&	(timeOut > 0) )
		{
			Sleep(10);
			timeOut -= 10;
		}
		timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */
		pahsc->pahsc_TimerID = 0;
	}
#else /* PA_USE_TIMER_CALLBACK */
#if PA_TRACE_START_STOP
    AddTraceMessage( "PaHost_StopEngine: thread ", (int) pahsc->pahsc_EngineThread );
#endif
    if( (past->past_OutputDeviceID != paNoDevice) &&
		(past->past_IsActive) &&
		(pahsc->pahsc_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( pahsc->pahsc_EngineThread, timeOut );
		if( got == WAIT_TIMEOUT )
		{
			ERR_RPT(("PaHost_StopEngine: timed out while waiting for background thread.\n"));
			return paTimedOut;
		}
		CloseHandle( pahsc->pahsc_EngineThread );
		pahsc->pahsc_EngineThread = NULL;
    }
#endif /* PA_USE_TIMER_CALLBACK */
	past->past_IsActive = 0;
	return paNoError;
}
/*************************************************************************/
PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
{
	MMRESULT mr;
	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return paNoError;
	(void) abort;
    if( pahsc->pahsc_HWaveIn != NULL )
	{
		mr = waveInReset( pahsc->pahsc_HWaveIn );
		if( mr != MMSYSERR_NOERROR )
		{
			sPaHostError = mr;
			return paHostError;
		}
	}
	return paNoError;
}
/*************************************************************************/
PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
{
	MMRESULT mr;
	PaHostSoundControl *pahsc;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return paNoError;
	(void) abort;
#if PA_TRACE_START_STOP
    AddTraceMessage( "PaHost_StopOutput: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
#endif
   if( pahsc->pahsc_HWaveOut != NULL )
	{
		mr = waveOutReset( pahsc->pahsc_HWaveOut );
		if( mr != MMSYSERR_NOERROR )
		{
			sPaHostError = mr;
			return paHostError;
		}
	}
	return paNoError;
}
/*******************************************************************/
PaError PaHost_CloseStream( internalPortAudioStream   *past )
{
	int                 i;
	PaHostSoundControl *pahsc;
	if( past == NULL ) return paBadStreamPtr;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return paNoError;
#if PA_TRACE_START_STOP
    AddTraceMessage( "PaHost_CloseStream: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
#endif
/* Free data and device for output. */
    if( pahsc->pahsc_HWaveOut )
	{
        if( pahsc->pahsc_OutputBuffers )
		{
            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
			{
                waveOutUnprepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );
                GlobalFree( pahsc->pahsc_OutputBuffers[i].lpData ); /* MEM */
            }
            GlobalFree( pahsc->pahsc_OutputBuffers ); /* MEM */
        }
        waveOutClose( pahsc->pahsc_HWaveOut );
    }
 /* Free data and device for input. */
   if( pahsc->pahsc_HWaveIn )
	{
        if( pahsc->pahsc_InputBuffers )
		{
            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
			{
                waveInUnprepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );
                GlobalFree( pahsc->pahsc_InputBuffers[i].lpData ); /* MEM */
            }
            GlobalFree( pahsc->pahsc_InputBuffers ); /* MEM */
        }
        waveInClose( pahsc->pahsc_HWaveIn );
    }
#if (PA_USE_TIMER_CALLBACK == 0)
    if( pahsc->pahsc_AbortEventInited ) CloseHandle( pahsc->pahsc_AbortEvent );
    if( pahsc->pahsc_BufferEventInited ) CloseHandle( pahsc->pahsc_BufferEvent );
#endif
	if( pahsc->pahsc_StreamLockInited )
	DeleteCriticalSection( &pahsc->pahsc_StreamLock );
	PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */
	past->past_DeviceData = NULL;
	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     hostVersion;
	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 ); */

/* GJG20020928 - GetEnvironmentVariable not supported under Windows CE. */
/*  ref. Programming Microsoft Windows CE 2nd Ed. Douglas Boling p.488 */
	hresult=0; 
	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
	{
		minLatencyMsec = atoi( envbuf );
	}
	else
	{
/* Set minimal latency based on whether NT or Win95.
 * NT has higher latency.
 */
/*		hostVersion = GetVersion(); */
/* GJG20020928 - GetVersion not supported by Windows CE */
/* Windows CE can call GetVersionEx() but a structure needs to be defined for the info. */
/* I am going to just return 1 and ask the developers if they wish to change this. */
        hostVersion=1;	/* 0=NT/Win2000/XP; 1=Win95/98/Me	
		
/* High bit clear if NT */
		minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : 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 )
				{
                    GlobalFree( (char*)sDevicePtrs[i]->name ); /* MEM */
                    GlobalFree( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */
                    GlobalFree( sDevicePtrs[i] ); /* MEM */
                }
            }
            GlobalFree( sDevicePtrs ); /* MEM */
            sDevicePtrs = NULL;
        }
        sNumDevices = 0;
    }
    return paNoError;
}
/*************************************************************************/
void Pa_Sleep( long msec )
{
	Sleep( msec );
}
/*************************************************************************
 * 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 )
{
	void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */
	return addr;
}
/*************************************************************************
 * 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 )
{
	if( addr != NULL ) GlobalFree( addr ); /* MEM */
}
/***********************************************************************/
PaError PaHost_StreamActive( internalPortAudioStream   *past )
{
	PaHostSoundControl *pahsc;
	if( past == NULL ) return paBadStreamPtr;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return paInternalError;
	return (PaError) past->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( PaHostSoundControl *pahsc )
{
	MMRESULT  mr;
	MMTIME    mmtime;
	mmtime.wType = TIME_SAMPLES;
	if( pahsc->pahsc_HWaveOut != NULL )
	{
		mr = waveOutGetPosition( pahsc->pahsc_HWaveOut, &mmtime, sizeof(mmtime) );
	}
	else
	{
		mr = waveInGetPosition( pahsc->pahsc_HWaveIn, &mmtime, sizeof(mmtime) );
	}
	if( mr != MMSYSERR_NOERROR )
	{
		sPaHostError = mr;
		return paHostError;
	}
/* This data has two variables and is shared by foreground and background. */
/* So we need to make it thread safe. */
	EnterCriticalSection( &pahsc->pahsc_StreamLock );
		pahsc->pahsc_FramesPlayed += ((long)mmtime.u.sample) - pahsc->pahsc_LastPosition;
		pahsc->pahsc_LastPosition = (long)mmtime.u.sample;
    LeaveCriticalSection( &pahsc->pahsc_StreamLock );
	return paNoError;
}
/*************************************************************************/
PaTimestamp Pa_StreamTime( PortAudioStream *stream )
{
	PaHostSoundControl *pahsc;
	internalPortAudioStream   *past = (internalPortAudioStream *) stream;
	if( past == NULL ) return paBadStreamPtr;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
	PaHost_UpdateStreamTime( pahsc );
	return pahsc->pahsc_FramesPlayed;
}

⌨️ 快捷键说明

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