📄 pthread-pa_sgi.c
字号:
/*-----------------------------------------------------*/
PaError PaHost_StartOutput(internalPortAudioStream *past)
{
return paNoError; /* Hmm, not implemented yet? */
}
PaError PaHost_StartInput(internalPortAudioStream *past)
{
return paNoError;
}
/*------------------------------------------------------------------------------*/
PaError PaHost_StartEngine(internalPortAudioStream *past)
{
PaHostSoundControl *pahsc;
int hres;
PaError result = paNoError;
if (!past) /* Test argument. */
{
ERR_RPT(("PaHost_StartEngine(NULL)!\n"));
return paBadStreamPtr;
}
pahsc = (PaHostSoundControl*)past->past_DeviceData;
if (!pahsc)
{
ERR_RPT(("PaHost_StartEngine(arg): arg->past_DeviceData == NULL!\n"));
return paHostError;
}
past->past_StopSoon = 0; /* Assume SGI ALport is already opened! */
past->past_StopNow = 0;
past->past_IsActive = 1;
DBUG(("PaHost_StartEngine() called.\n"));
/* Use pthread_create() instead of __clone() because: */
/* - pthread_create also works for other UNIX systems like Solaris, */
/* - Java HotSpot VM crashes in pthread_setcanceltype() when using __clone(). */
hres = pthread_create(&(pahsc->pahsc_ThreadPID), /* SPAWN AUDIO-CHILD. */
NULL, /* pthread_attr_t * attr */
(void*)Pa_SgiAudioProcess,
past);
if (hres)
{
result = paHostError;
sPaHostError = hres;
ERR_RPT(("PaHost_StartEngine() failed to spawn audio-thread.\n"));
}
return result;
}
/*------------------------------------------------------------------------------*/
PaError PaHost_StopEngine(internalPortAudioStream *past, int abort)
{
int hres;
PaError result = paNoError;
PaHostSoundControl *pahsc;
DBUG(("PaHost_StopEngine() called.\n"));
if (!past)
return paBadStreamPtr;
pahsc = (PaHostSoundControl*)past->past_DeviceData;
if (pahsc == NULL)
return result; /* paNoError (already stopped, no err?). */
past->past_StopSoon = 1; /* Tell background thread to stop generating */
if (abort) /* more and to let current data play out. If */
past->past_StopNow = 1; /* aborting, tell backgrnd thread to stop NOW! */
if (pahsc->pahsc_ThreadPID != -1) /* Join thread to recover memory resources. */
{
DBUG(("pthread_join() called.\n"));
hres = pthread_join(pahsc->pahsc_ThreadPID, NULL);
if (hres)
{
result = paHostError;
sPaHostError = hres;
ERR_RPT(("PaHost_StopEngine() failed pthread_join().\n"));
}
pahsc->pahsc_ThreadPID = -1;
}
past->past_IsActive = 0;
return result;
}
/*---------------------------------------------------------------*/
PaError PaHost_StopOutput(internalPortAudioStream *past, int abort)
{
return paNoError; /* Not implemented yet? */
}
PaError PaHost_StopInput(internalPortAudioStream *past, int abort )
{
return paNoError;
}
/*******************************************************************/
PaError PaHost_CloseStream(internalPortAudioStream *past)
{
PaHostSoundControl *pahsc;
PaError result = paNoError;
DBUG(("PaHost_CloseStream() called.\n"));
if (past == NULL)
return paBadStreamPtr;
pahsc = (PaHostSoundControl *) past->past_DeviceData;
if (pahsc == NULL) /* If pahsc not NULL, past_DeviceData will be freed, and set to NULL. */
return result; /* This test prevents from freeing NULL-pointers. */
if (pahsc->pahsc_ALportIN)
{
if (ALcloseport(pahsc->pahsc_ALportIN))
result = translateSGIerror(); /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
else /* But go on anyway... to release other stuff... */
pahsc->pahsc_ALportIN = (ALport)0;
}
if (pahsc->pahsc_ALportOUT)
{
if (ALcloseport(pahsc->pahsc_ALportOUT))
result = translateSGIerror();
else
pahsc->pahsc_ALportOUT = (ALport)0;
}
if (pahsc->pahsc_NativeInputBuffer)
{
PaHost_FreeFastMemory(pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_BytesPerInputBuffer);
pahsc->pahsc_NativeInputBuffer = NULL;
}
if (pahsc->pahsc_NativeOutputBuffer)
{
PaHost_FreeFastMemory(pahsc->pahsc_NativeOutputBuffer, pahsc->pahsc_BytesPerOutputBuffer);
pahsc->pahsc_NativeOutputBuffer = NULL;
}
PaHost_FreeFastMemory(pahsc, sizeof(PaHostSoundControl));
past->past_DeviceData = NULL; /* PaHost_OpenStream() allocated FAST. */
return result;
}
/*************************************************************************
** 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 )
{
return 2;
}
/* Hmmm, the note above isn't appropriate for SGI I'm afraid... */
/* Do we HAVE to do it this way under IRIX???.... */
/*--------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
PaError PaHost_Term(void) /* Frees all of the linked audio-devices. */
{ /* Called by Pa_Terminate() from pa_lib.c. */
internalPortAudioDevice *pad = sDeviceList,
*nxt;
while (pad)
{
DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName));
nxt = pad->pad_Next;
PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice));
pad = nxt; /* PaHost_Init allocated this FAST MEM.*/
}
sDeviceList = (internalPortAudioDevice*)NULL;
return 0; /* Got rid of sNumDevices=0; */
}
/***********************************************************************/
void Pa_Sleep( long msec ) /* Sleep requested number of milliseconds. */
{
#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 physi- */
/* cal 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);
if (addr)
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)
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);
}
/*-------------------------------------------------------------------*/
PaTimestamp Pa_StreamTime( PortAudioStream *stream )
{
internalPortAudioStream *past = (internalPortAudioStream *) stream;
/* FIXME - return actual frames played, not frames generated.
** Need to query the output device somehow.
*/
return past->past_FrameCount;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -