📄 pthread-pa_sgi.c
字号:
ERR_RPT(("%smax float value is zero.\n", a));
return paHostError; /* Generic PaError. */
case AL_BAD_WIDTH:
ERR_RPT(("%sunsupported samplewidth.\n", a));
return paHostError; /* Generic PaError. */
case AL_BAD_QSIZE:
ERR_RPT(("%sinvalid queue size.\n", a));
return paHostError; /* Generic PaError. */
case AL_BAD_PVBUFFER:
ERR_RPT(("%sPVbuffer null.\n", a));
return paHostError; /* Generic PaError. */
case AL_BAD_BUFFERLENGTH_NEG:
ERR_RPT(("%snegative bufferlength.\n", a));
return paHostError; /* Generic PaError. */
case AL_BAD_BUFFERLENGTH_ODD:
ERR_RPT(("%sodd bufferlength.\n", a));
return paHostError; /* Generic PaError. */
case AL_BAD_PARAM:
ERR_RPT(("%sparameter not valid for device.\n", a));
return paHostError; /* Generic PaError. */
default:
ERR_RPT(("%sunknown error.\n", a));
return paHostError; /* Generic PaError. */
}
}
/*------------------------------------------------------------------------------------------*/
/* Tries to set various rates and formats and fill in the device info structure. */
static PaError Pa_sgiQueryDevice(long ALdev, /* (AL_DEFAULT_DEVICE) */
PaDeviceID id, /* (DefaultI|ODeviceID()) */
char* name, /* (for example "SGI AL") */
internalPortAudioDevice* pad) /* Result written to pad. */
{
int format;
long min, max; /* To catch hardware characteristics. */
ALseterrorhandler(0); /* 0 = turn off the default error handler. */
/*--------------------------------------------------------------------------------------*/
pad->pad_ALdevice = ALdev; /* Set the AL device number. */
pad->pad_DeviceID = id; /* Set the PA device number. */
if (strlen(name) > MAX_CHARS_DEVNAME) /* MAX_CHARS defined above. */
{
ERR_RPT(("Pa_QueryDevice(): name too long (%s).\n", name));
return paHostError;
}
strcpy(pad->pad_DeviceName, name); /* Write name-string. */
pad->pad_Info.name = pad->pad_DeviceName; /* Set pointer,..hmmm. */
/*--------------------------------- natively supported sample formats: -----------------*/
pad->pad_Info.nativeSampleFormats = paInt16; /* Later also include paFloat32 | ..| etc. */
/* Then also choose other CallConvertXX()! */
/*--------------------------------- number of available i/o channels: ------------------*/
if (ALgetminmax(ALdev, AL_INPUT_COUNT, &min, &max))
return translateSGIerror();
pad->pad_Info.maxInputChannels = max;
DBUG(("Pa_QueryDevice: maxInputChannels = %d\n", pad->pad_Info.maxInputChannels))
if (ALgetminmax(ALdev, AL_OUTPUT_COUNT, &min, &max))
return translateSGIerror();
pad->pad_Info.maxOutputChannels = max;
DBUG(("Pa_QueryDevice: maxOutputChannels = %d\n", pad->pad_Info.maxOutputChannels))
/*--------------------------------- supported samplerates: ----------------------*/
pad->pad_Info.numSampleRates = 7;
pad->pad_Info.sampleRates = pad->pad_SampleRates;
pad->pad_SampleRates[0] = (double)AL_RATE_8000; /* long -> double. */
pad->pad_SampleRates[1] = (double)AL_RATE_11025;
pad->pad_SampleRates[2] = (double)AL_RATE_16000;
pad->pad_SampleRates[3] = (double)AL_RATE_22050;
pad->pad_SampleRates[4] = (double)AL_RATE_32000;
pad->pad_SampleRates[5] = (double)AL_RATE_44100;
pad->pad_SampleRates[6] = (double)AL_RATE_48000;
if (ALgetminmax(ALdev, AL_INPUT_RATE, &min, &max)) /* Ask INPUT rate-max. */
return translateSGIerror(); /* double -> long. */
if (max != (long)(0.5 + pad->pad_SampleRates[6])) /* FP-compare not recommndd. */
goto weird;
if (ALgetminmax(ALdev, AL_OUTPUT_RATE, &min, &max)) /* Ask OUTPUT rate-max. */
return translateSGIerror();
if (max != (long)(0.5 + pad->pad_SampleRates[6]))
{
weird: ERR_RPT(("Pa_sgiQueryDevice() did not confirm max samplerate (%ld)\n",max));
return paHostError; /* Or make it a warning and just carry on... */
}
/*-------------------------------------------------------------------------------*/
return paNoError;
}
/*--------------------------------------------------------------------------------*/
int Pa_CountDevices() /* Name of this function suggests it only counts and */
{ /* is NOT destructive, it however resets whole PA ! */
int numDevices = 0; /* Let 's not do that here. */
internalPortAudioDevice* currentDevice = sDeviceList; /* COPY GLOBAL VAR. */
#if 0 /* Remains from linux_oss v15: Pa_Initialize(), on */
if (!currentDevice) /* its turn, calls PaHost_Init() via file pa_lib.c. */
Pa_Initialize(); /* Isn't that a bit too 'rude'? Don't be too */
#endif /* friendly to clients that forgot to initialize PA. */
while (currentDevice) /* Slower but more elegant than the sNumDevices-way: */
{
numDevices++;
currentDevice = currentDevice->pad_Next;
}
return numDevices;
}
/*-------------------------------------------------------------------------------*/
static internalPortAudioDevice *Pa_GetInternalDevice(PaDeviceID id)
{
int numDevices = 0;
internalPortAudioDevice *res = (internalPortAudioDevice*)NULL;
internalPortAudioDevice *pad = sDeviceList; /* COPY GLOBAL VAR. */
while (pad) /* pad may be NULL, that's ok, return 0. */
{ /* (Added ->pad_DeviceID field to the pad-struct, Pieter, 2001.) */
if (pad->pad_DeviceID == id) /* This the device we were looking for? */
res = pad; /* But keep on(!) counting so we don't */
numDevices++; /* have to call Pa_CountDevices() later. */
pad = pad->pad_Next; /* Advance to the next device or NULL. */
} /* No assumptions about order of ID's in */
if (!res) /* the list. */
ERR_RPT(("Pa_GetInternalDevice() could not find specified ID (%d).\n",id));
if ((id < 0) || (id >= numDevices))
{
ERR_RPT(("Pa_GetInternalDevice() supplied with an illegal ID (%d).\n",id));
#if 1 /* Be strict, even when found, */
res = (internalPortAudioDevice*)NULL; /* do not accept illegal ID's. */
#endif
}
return res;
}
/*----------------------------------------------------------------------*/
const PaDeviceInfo* Pa_GetDeviceInfo(PaDeviceID id)
{
PaDeviceInfo* res = (PaDeviceInfo*)NULL;
internalPortAudioDevice* pad = Pa_GetInternalDevice(id); /* Call. */
if (pad)
res = &pad->pad_Info; /* Not finding the specified ID is not */
if (!res) /* the same as &pad->pad_Info == NULL. */
ERR_RPT(("Pa_GetDeviceInfo() could not find it (ID=%d).\n", id));
return res; /* So (maybe) a second/third ERR_RPT(). */
}
/*------------------------------------------------*/
PaDeviceID Pa_GetDefaultInputDeviceID(void)
{
return 0; /* 0 is the default device ID. */
}
/*------------------------------------------------*/
PaDeviceID Pa_GetDefaultOutputDeviceID(void)
{
return 0;
}
/*-------------------------------------------------------------------------------------------------*/
/* Build linked a list with all the available audio devices on this SGI machine (only 1 for now). */
PaError PaHost_Init(void) /* Called by Pa_Initialize() from pa_lib.c. */
{
internalPortAudioDevice* pad;
PaError r = paNoError;
int audioLibFileID; /* To test for the presence of audio. */
if (sDeviceList) /* Allow re-init, only warn, no error. */
{
ERR_RPT(("Warning: PaHost_Init() did not really re-init PA.\n"));
return r;
}
/*------------- ADD THE SGI DEFAULT DEVICE TO THE LIST: ---------------------------------------*/
audioLibFileID = open("/dev/hdsp/hdsp0master", O_RDONLY); /* Try to open Indigo style audio */
if (audioLibFileID < 0) /* IO port. On failure, machine */
{ /* has no audio ability. */
ERR_RPT(("PaHost_Init(): This machine has no (Indigo-style) audio abilities.\n"));
return paHostError;
}
close(audioLibFileID); /* Allocate fast mem to hold device info. */
pad = PaHost_AllocateFastMemory(sizeof(internalPortAudioDevice));
if (pad == NULL)
return paInsufficientMemory;
memset(pad, 0, sizeof(internalPortAudioDevice)); /* "pad->pad_Next = NULL" is more elegant. */
r = Pa_sgiQueryDevice(AL_DEFAULT_DEVICE, /* Set AL device num (AL_DEFAULT_DEVICE). */
Pa_GetDefaultOutputDeviceID(),/* Set PA device num (or InputDeviceID()). */
"AL default", /* A suitable name. */
pad); /* Write args and queried info into pad. */
if (r != paNoError)
{
ERR_RPT(("Pa_QueryDevice for '%s' returned: %d\n", pad->pad_DeviceName, r));
PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice)); /* sDeviceList still NULL ! */
}
else
sDeviceList = pad; /* First element in linked list. pad->pad_Next already NULL. */
/*------------- QUERY AND ADD MORE POSSIBLE SGI DEVICES TO THE LINKED LIST: -------------------*/
/*---------------------------------------------------------------------------------------------*/
return r;
}
/*---------------------------------------------------------------------------------------------------*/
static PaError Pa_SgiAudioProcess(internalPortAudioStream *past) /* Spawned by PaHost_StartEngine(). */
{
PaError result = paNoError;
PaHostSoundControl *pahsc;
if (!past)
return paBadStreamPtr;
pahsc = (PaHostSoundControl*)past->past_DeviceData;
if (!pahsc)
return paInternalError;
past->past_IsActive = 1; /* Wasn't this already done by the calling parent?! */
DBUG(("entering thread.\n"));
while (!past->past_StopSoon) /* OR-ing StopSoon and StopNow here gives problems! */
{
/*---------------------------------------- INPUT: ------------------------------------*/
if (pahsc->pahsc_NativeInputBuffer) /* Then pahsc_ALportIN should also be there! */
{
while (ALgetfilled(pahsc->pahsc_ALportIN) < pahsc->pahsc_SamplesPerInputBuffer)
{
/* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
if (past->past_StopNow) /* Don't let ALreadsamps() block */
goto done;
}
if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer,
pahsc->pahsc_SamplesPerInputBuffer)) /* Number of samples instead */
{ /* of number of frames. */
ERR_RPT(("ALreadsamps() failed.\n"));
result = paInternalError;
goto done;
}
}
/*---------------------------------------------------- USER CALLBACK ROUTINE: ----------*/
/* DBUG(("Calling Pa_CallConvertInt16()...\n")); */
Pa_StartUsageCalculation(past); /* Convert 16 bit native data to */
result = Pa_CallConvertInt16(past, /* user data and call user routine. */
pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_NativeOutputBuffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -