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

📄 pa_win_wmme.c

📁 ppciaxclient softphone
💻 C
📖 第 1 页 / 共 4 页
字号:
	}
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = (WORD) past->past_NumInputChannels;
	wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;
	wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * past->past_SampleRate);
	wfx.nBlockAlign = (WORD)bytesPerInputFrame;
	wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/past->past_NumInputChannels) * 8);
	wfx.cbSize = 0;
	inputMmId = PaDeviceIdToWinId( past->past_InputDeviceID );
#if PA_USE_TIMER_CALLBACK
	mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,
	                  0, 0, CALLBACK_NULL );
#else
	mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,
	                  (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );
#endif
	if( mr != MMSYSERR_NOERROR )
	{
		ERR_RPT(("PortAudio: PaHost_OpenInputStream() failed!\n"));
		result = paHostError;
		sPaHostError = mr;
		goto error;
	}
/* Allocate an array to hold the buffer pointers. */
	pahsc->pahsc_InputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */
	if( pahsc->pahsc_InputBuffers == NULL )
	{
		result = paInsufficientMemory;
		goto error;
	}
/* Allocate each buffer. */
	for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
	{
		pahsc->pahsc_InputBuffers[i].lpData = (char *)GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostInputBuffer ); /* MEM */
		if( pahsc->pahsc_InputBuffers[i].lpData == NULL )
		{
			result = paInsufficientMemory;
			goto error;
		}
		pahsc->pahsc_InputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostInputBuffer;
		pahsc->pahsc_InputBuffers[i].dwUser = i;
		if( ( mr = waveInPrepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )
		{
			result = paHostError;
			sPaHostError = mr;
			goto error;
		}
	}
	return result;
error:
	return result;
}
/*******************************************************************/
PaError PaHost_OpenOutputStream( internalPortAudioStream   *past )
{
	MMRESULT         mr;
	PaError          result = paNoError;
	PaHostSoundControl *pahsc;
	int              i;
	int              outputMmID;
	int              bytesPerOutputFrame;
	WAVEFORMATEX     wfx;
	const PaDeviceInfo *pad;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
	DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID));
	pad = Pa_GetDeviceInfo( past->past_OutputDeviceID );
	if( pad == NULL ) return paInternalError;
	switch( pad->nativeSampleFormats  )
	{
		case paInt32:
		case paFloat32:
			bytesPerOutputFrame = sizeof(float) * past->past_NumOutputChannels;
			break;
		default:
			bytesPerOutputFrame = sizeof(short) * past->past_NumOutputChannels;
			break;
	}
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = (WORD) past->past_NumOutputChannels;
	wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;
	wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * past->past_SampleRate);
	wfx.nBlockAlign = (WORD)bytesPerOutputFrame;
	wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/past->past_NumOutputChannels) * 8);
	wfx.cbSize = 0;
	outputMmID = PaDeviceIdToWinId( past->past_OutputDeviceID );
#if PA_USE_TIMER_CALLBACK
	mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,
	                  0, 0, CALLBACK_NULL );
#else
	        
	pahsc->pahsc_AbortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	if( pahsc->pahsc_AbortEvent == NULL )
	{
		result = paHostError;
		sPaHostError = GetLastError();
		goto error;
	}
	pahsc->pahsc_AbortEventInited = 1;
	mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,
	                  (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );
#endif
	if( mr != MMSYSERR_NOERROR )
	{
		ERR_RPT(("PortAudio: PaHost_OpenOutputStream() failed!\n"));
		result = paHostError;
		sPaHostError = mr;
		goto error;
	}
/* Allocate an array to hold the buffer pointers. */
	pahsc->pahsc_OutputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */
	if( pahsc->pahsc_OutputBuffers == NULL )
	{
		result = paInsufficientMemory;
		goto error;
	}
/* Allocate each buffer. */
	for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
	{
		pahsc->pahsc_OutputBuffers[i].lpData = (char *) GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostOutputBuffer ); /* MEM */
		if( pahsc->pahsc_OutputBuffers[i].lpData == NULL )
		{
			result = paInsufficientMemory;
			goto error;
		}
		pahsc->pahsc_OutputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostOutputBuffer;
		pahsc->pahsc_OutputBuffers[i].dwUser = i;
		if( (mr = waveOutPrepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )
		{
			result = paHostError;
			sPaHostError = mr;
			goto error;
		}
	}
	return result;
error:
	return result;
}
/*******************************************************************/
PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past )
{
	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
	return pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer;
}
/*******************************************************************
* Determine number of WAVE Buffers
* and how many User Buffers we can put into each WAVE buffer.
*/
static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
{
	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
	unsigned int  minNumBuffers;
	int           minFramesPerHostBuffer;
	int           maxFramesPerHostBuffer;
	int           minTotalFrames;
	int           userBuffersPerHostBuffer;
	int           framesPerHostBuffer;
	int           numHostBuffers;
/* Calculate minimum and maximum sizes based on timing and sample rate. */
	minFramesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);
	minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;
	DBUG(("PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer ));
	maxFramesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);
	maxFramesPerHostBuffer = (maxFramesPerHostBuffer + 7) & ~7;
	DBUG(("PaHost_CalcNumHostBuffers: maxFramesPerHostBuffer = %d\n", maxFramesPerHostBuffer ));
/* Determine number of user buffers based on minimum latency. */
	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;
	DBUG(("PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\n", past->past_NumUserBuffers ));
	minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer;
/* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */
	if( (int) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )
	{
		userBuffersPerHostBuffer =
			(minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /
			past->past_FramesPerUserBuffer;
	}
	else
	{
		userBuffersPerHostBuffer = 1;
	}
	framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
/* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */
	numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
/* Make sure we have anough WAVE buffers. */
	if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)
	{
		numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;
	}
	else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) && 
	         ((int) past->past_FramesPerUserBuffer < (maxFramesPerHostBuffer/2) ) )
	{
/* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */
		while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)
		{
			userBuffersPerHostBuffer += 1;
			framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
			numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
	/* If we have gone too far, back up one. */
			if( (framesPerHostBuffer > maxFramesPerHostBuffer) ||
				(numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )
			{
				userBuffersPerHostBuffer -= 1;
				framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
				numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
				break;
			}
		}
	}
	
	pahsc->pahsc_UserBuffersPerHostBuffer = userBuffersPerHostBuffer;
	pahsc->pahsc_FramesPerHostBuffer = framesPerHostBuffer;
	pahsc->pahsc_NumHostBuffers = numHostBuffers;
	DBUG(("PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\n", pahsc->pahsc_UserBuffersPerHostBuffer ));
	DBUG(("PaHost_CalcNumHostBuffers: pahsc_NumHostBuffers = %d\n", pahsc->pahsc_NumHostBuffers ));
	DBUG(("PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\n", pahsc->pahsc_FramesPerHostBuffer ));
	DBUG(("PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\n", past->past_NumUserBuffers ));
}
/*******************************************************************/
PaError PaHost_OpenStream( internalPortAudioStream   *past )
{
	PaError             result = paNoError;
	PaHostSoundControl *pahsc;
/* Allocate and initialize host data. */
	pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */
	if( pahsc == NULL )
	{
		result = paInsufficientMemory;
		goto error;
	}
	memset( pahsc, 0, sizeof(PaHostSoundControl) );
	past->past_DeviceData = (void *) pahsc;
/* Figure out how user buffers fit into WAVE buffers. */
	PaHost_CalcNumHostBuffers( past );
	{
		int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate);
		DBUG(("PortAudio on WMME - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(past), msecLatency ));
	}
    InitializeCriticalSection( &pahsc->pahsc_StreamLock );
    pahsc->pahsc_StreamLockInited = 1;
	
#if (PA_USE_TIMER_CALLBACK == 0)
    pahsc->pahsc_BufferEventInited = 0;
    pahsc->pahsc_BufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    if( pahsc->pahsc_BufferEvent == NULL ){
        result = paHostError;
        sPaHostError = GetLastError();
        goto error;
    }
    pahsc->pahsc_BufferEventInited = 1;
#endif /* (PA_USE_TIMER_CALLBACK == 0) */
/* ------------------ OUTPUT */
	pahsc->pahsc_BytesPerUserOutputBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels * sizeof(short);
	pahsc->pahsc_BytesPerHostOutputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserOutputBuffer;
	if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) )
	{
		result = PaHost_OpenOutputStream( past );
		if( result < 0 ) goto error;
	}
/* ------------------ INPUT */
	pahsc->pahsc_BytesPerUserInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short);
	pahsc->pahsc_BytesPerHostInputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserInputBuffer;
	if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) )
	{
		result = PaHost_OpenInputStream( past );
		if( result < 0 ) goto error;
	}
/* Calculate scalar used in CPULoad calculation. */ 
	{
		LARGE_INTEGER frequency;
		if( QueryPerformanceFrequency( &frequency ) == 0 )
		{
			pahsc->pahsc_InverseTicksPerHostBuffer = 0.0;
		}
		else
		{
			pahsc->pahsc_InverseTicksPerHostBuffer = past->past_SampleRate /
				( (double)frequency.QuadPart * past->past_FramesPerUserBuffer * pahsc->pahsc_UserBuffersPerHostBuffer );
			DBUG(("pahsc_InverseTicksPerHostBuffer = %g\n", pahsc->pahsc_InverseTicksPerHostBuffer ));
		}
	}
	return result;
error:
	PaHost_CloseStream( past );
	return result;
}
/*************************************************************************/
PaError PaHost_StartOutput( internalPortAudioStream *past )
{
	MMRESULT         mr;
	PaHostSoundControl *pahsc;
	PaError          result = paNoError;
	int              i;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
    if( past->past_OutputDeviceID != paNoDevice )
	{
        if( (mr = waveOutPause( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )
		{
			result = paHostError;
			sPaHostError = mr;
			goto error;
		}
        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
		{
            ZeroMemory( pahsc->pahsc_OutputBuffers[i].lpData, pahsc->pahsc_OutputBuffers[i].dwBufferLength );
            mr = waveOutWrite( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );
			if( mr != MMSYSERR_NOERROR )
			{
				result = paHostError;
				sPaHostError = mr;
				goto error;
			}
			past->past_FrameCount += pahsc->pahsc_FramesPerHostBuffer;
        }
        pahsc->pahsc_CurrentOutputBuffer = 0;
		if( (mr = waveOutRestart( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )
		{
			result = paHostError;
			sPaHostError = mr;
			goto error;
		}
	}
	DBUG(("PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\n", hr));
error:
	return result;
}
/*************************************************************************/
PaError PaHost_StartInput( internalPortAudioStream *past )
{
	PaError          result = paNoError;
	MMRESULT         mr;
	int              i;
	PaHostSoundControl *pahsc;
	pahsc = (PaHostSoundControl *) past->past_DeviceData;
    if( past->past_InputDeviceID != paNoDevice )
    {
        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
		{
            mr = waveInAddBuffer( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );
			if( mr != MMSYSERR_NOERROR )
			{
				result = paHostError;
				sPaHostError = mr;
				goto error;
			}
        }
        pahsc->pahsc_CurrentInputBuffer = 0;
		mr = waveInStart( pahsc->pahsc_HWaveIn );
		DBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", hr));
		if( mr != MMSYSERR_NOERROR )
		{
			result = paHostError;
			sPaHostError = mr;
			goto error;
		}
	}
error:
	return result;
}
/*************************************************************************/
PaError PaHost_StartEngine( internalPortAudioStream *past )
{
	PaError             result = paNoError;
	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
#if PA_USE_TIMER_CALLBACK
	int                 resolution;
	int                 bufsPerTimerCallback;
	int                 msecPerBuffer;
#endif /* PA_USE_TIMER_CALLBACK */

	//GJG20030416 I use this file to get runtime info
	//you can pull this logging code out once everything is working
    FILE *pa_stdout;   // for portaudio logging
    char pa_buf[256];  //char buffer for text
	int pa_len;        //length in bytes to write
	int pa_nbw;        //number of bytes written

⌨️ 快捷键说明

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