📄 pa_unix.c
字号:
if( past->past_NumInputChannels > 0)
{
pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);
if( pahsc->pahsc_NativeInputBuffer == NULL )
{
result = paInsufficientMemory;
goto error;
}
}
pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer *
past->past_NumOutputChannels * sizeof(short);
if( past->past_NumOutputChannels > 0)
{
pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);
if( pahsc->pahsc_NativeOutputBuffer == NULL )
{
result = paInsufficientMemory;
goto error;
}
}
/* DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); */
minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;
pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer);
DBUG(("past_SampleRate = %g\n", past->past_SampleRate ));
DBUG(("past_FramesPerUserBuffer = %d\n", past->past_FramesPerUserBuffer ));
DBUG(("pahsc_InverseMicrosPerBuffer = %g\n", pahsc->pahsc_InverseMicrosPerBuffer ));
/* ------------------------- OPEN DEVICE -----------------------*/
/* just output */
if (past->past_OutputDeviceID == past->past_InputDeviceID)
{
if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )
{
pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName ));
/* dmazzoni: test it first in nonblocking mode to
make sure the device is not busy */
pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDWR|O_NONBLOCK);
if(pahsc->pahsc_InputHandle==-1)
{
ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
result = paHostError;
goto error;
}
close(pahsc->pahsc_InputHandle);
pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle =
open(pad->pad_DeviceName,O_RDWR);
if(pahsc->pahsc_InputHandle==-1)
{
ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
result = paHostError;
goto error;
}
Pa_SetLatency( pahsc->pahsc_OutputHandle,
past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
past->past_NumOutputChannels );
result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,
past->past_NumOutputChannels, (int)past->past_SampleRate );
}
}
else
{
if (past->past_NumOutputChannels > 0)
{
pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName ));
/* dmazzoni: test it first in nonblocking mode to
make sure the device is not busy */
pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY|O_NONBLOCK);
if(pahsc->pahsc_OutputHandle==-1)
{
ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
result = paHostError;
goto error;
}
close(pahsc->pahsc_OutputHandle);
pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY);
if(pahsc->pahsc_OutputHandle==-1)
{
ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
result = paHostError;
goto error;
}
Pa_SetLatency( pahsc->pahsc_OutputHandle,
past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
past->past_NumOutputChannels );
result = Pa_SetupOutputDeviceFormat( pahsc->pahsc_OutputHandle,
past->past_NumOutputChannels, (int)past->past_SampleRate );
}
if (past->past_NumInputChannels > 0)
{
pad = Pa_GetInternalDevice( past->past_InputDeviceID );
DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName ));
/* dmazzoni: test it first in nonblocking mode to
make sure the device is not busy */
pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY|O_NONBLOCK);
if(pahsc->pahsc_InputHandle==-1)
{
ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
result = paHostError;
goto error;
}
close(pahsc->pahsc_InputHandle);
pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY);
if(pahsc->pahsc_InputHandle==-1)
{
ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
result = paHostError;
goto error;
}
Pa_SetLatency( pahsc->pahsc_InputHandle, /* DH20010115 - was OutputHandle! */
past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
past->past_NumInputChannels );
result = Pa_SetupInputDeviceFormat( pahsc->pahsc_InputHandle,
past->past_NumInputChannels, (int)past->past_SampleRate );
}
}
DBUG(("PaHost_OpenStream: SUCCESS - result = %d\n", result ));
return result;
error:
ERR_RPT(("PaHost_OpenStream: ERROR - result = %d\n", result ));
PaHost_CloseStream( past );
return result;
}
/*************************************************************************/
PaError PaHost_StartOutput( internalPortAudioStream *past )
{
past = past; /* unused */
return paNoError;
}
/*************************************************************************/
PaError PaHost_StartInput( internalPortAudioStream *past )
{
past = past; /* unused */
return paNoError;
}
/*************************************************************************/
PaError PaHost_StartEngine( internalPortAudioStream *past )
{
PaHostSoundControl *pahsc;
PaError result = paNoError;
int hres;
pahsc = (PaHostSoundControl *) past->past_DeviceData;
past->past_StopSoon = 0;
past->past_StopNow = 0;
past->past_IsActive = 1;
/* Use pthread_create() instead of __clone() because:
* - pthread_create also works for other UNIX systems like Solaris,
* - the Java HotSpot VM crashes in pthread_setcanceltype() when using __clone()
*/
hres = pthread_create(&(pahsc->pahsc_AudioThread),
NULL /*pthread_attr_t * attr*/,
(pthread_function_t)Pa_AudioThreadProc, past);
if( hres != 0 )
{
result = paHostError;
sPaHostError = hres;
pahsc->pahsc_IsAudioThreadValid = 0;
goto error;
}
pahsc->pahsc_IsAudioThreadValid = 1;
error:
return result;
}
/*************************************************************************/
PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
{
int hres;
PaError result = paNoError;
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;
/* Join thread to recover memory resources. */
if( pahsc->pahsc_IsAudioThreadValid )
{
/* This check is needed for GNUSTEP - SB20010904 */
if ( !pthread_equal( pahsc->pahsc_AudioThread, pthread_self() ) )
{
hres = pthread_join( pahsc->pahsc_AudioThread, NULL );
}
else
{
DBUG(("Play thread was stopped from itself - can't do pthread_join()\n"));
hres = 0;
}
if( hres != 0 )
{
result = paHostError;
sPaHostError = hres;
}
pahsc->pahsc_IsAudioThreadValid = 0;
}
past->past_IsActive = 0;
return result;
}
/*************************************************************************/
PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
{
past = past; /* unused */
abort = abort; /* unused */
return paNoError;
}
/*************************************************************************/
PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
{
past = past; /* unused */
abort = abort; /* unused */
return paNoError;
}
/*******************************************************************/
PaError PaHost_CloseStream( internalPortAudioStream *past )
{
PaHostSoundControl *pahsc;
if( past == NULL ) return paBadStreamPtr;
pahsc = (PaHostSoundControl *) past->past_DeviceData;
if( pahsc == NULL ) return paNoError;
if( pahsc->pahsc_OutputHandle != BAD_DEVICE_ID )
{
int err = 0;
DBUG(("PaHost_CloseStream: attempt to close output device handle = %d\n",
pahsc->pahsc_OutputHandle ));
Pa_FlushStream(pahsc->pahsc_OutputHandle);
err = close(pahsc->pahsc_OutputHandle);
if( err < 0 )
{
ERR_RPT(("PaHost_CloseStream: warning, closing output device failed.\n"));
}
}
if( (pahsc->pahsc_InputHandle != BAD_DEVICE_ID) &&
(pahsc->pahsc_InputHandle != pahsc->pahsc_OutputHandle) )
{
int err = 0;
DBUG(("PaHost_CloseStream: attempt to close input device handle = %d\n",
pahsc->pahsc_InputHandle ));
Pa_FlushStream(pahsc->pahsc_InputHandle);
err = close(pahsc->pahsc_InputHandle);
if( err < 0 )
{
ERR_RPT(("PaHost_CloseStream: warning, closing input device failed.\n"));
}
}
pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;
pahsc->pahsc_InputHandle = BAD_DEVICE_ID;
if( pahsc->pahsc_NativeInputBuffer )
{
free( pahsc->pahsc_NativeInputBuffer );
pahsc->pahsc_NativeInputBuffer = NULL;
}
if( pahsc->pahsc_NativeOutputBuffer )
{
free( pahsc->pahsc_NativeOutputBuffer );
pahsc->pahsc_NativeOutputBuffer = NULL;
}
free( pahsc );
past->past_DeviceData = NULL;
return paNoError;
}
/*************************************************************************/
PaError PaHost_Term( void )
{
/* Free all of the linked devices. */
internalPortAudioDevice *pad, *nextPad;
pad = sDeviceList;
while( pad != NULL )
{
nextPad = pad->pad_Next;
DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName ));
PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );
pad = nextPad;
}
sDeviceList = NULL;
return 0;
}
/*************************************************************************
* Sleep for the requested number of milliseconds.
*/
void Pa_Sleep( long msec )
{
#if 0
struct timeval timeout;
timeout.tv_sec = msec / 1000;
timeout.tv_usec = (msec % 1000) * 1000;
select( 0, NULL, NULL, NULL, &timeout );
#else
long usecs = msec * 1000;
usleep( usecs );
#endif
}
/*************************************************************************
* 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().
*/
void *PaHost_AllocateFastMemory( long numBytes )
{
void *addr = malloc( numBytes ); /* FIXME - do we need physical, wired, non-virtual memory? */
if( addr != NULL ) memset( addr, 0, numBytes );
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 )
{
numBytes = numBytes; /* unused */
if( addr != NULL ) free( addr );
}
/***********************************************************************/
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 != 0);
}
/***********************************************************************/
long Pa_GetHostError( void )
{
return (long) sPaHostError;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -