📄 pa_unix.c
字号:
/* Allocate native buffers. */ pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short); 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 ){ return paNoError;}/*************************************************************************/PaError PaHost_StartInput( internalPortAudioStream *past ){ 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 ){ return paNoError;}/*************************************************************************/PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ){ 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 ){ 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 + -