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

📄 pthread-pa_sgi.c

📁 ppciaxclient softphone
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * PortAudio Portable Real-Time Audio Library
 * Latest Version at: http://www.portaudio.com
 * SGI IRIX implementation by Pieter Suurmond, september 22, 2001 (#0.18).
 *
 * Copyright (c) 1999-2001 Phil Burk
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * Any person wishing to distribute modifications to the Software is
 * requested to send the modifications to the original developer so that
 * they can be incorporated into the canonical version.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/*
Modfication History:
  8/12/2001 - Pieter Suurmond - took the v15 pa_linux_oss.c file and started to adapt for IRIX 6.2.
  8/17/2001 - alpha release with IRIX sproc()-method, may sometimes let IRIX6.2 crash at closing audiostream.
  9/22/2001 - #0.18 pthread starts to work a bit:
              BUT UNDER IRIX6.2, I DON'T GET IT TO WORK REALLY CORRECTLY,
                                 this POSIX-attempt,
              DON'T USE THIS FILE FOR RELIABLE OPERATION, IT IS HERE JUST 
              FOR DOCUMENTATION/ARCHIVE... OR FOR ANYONE WHO WANTS TO FIX......
TODO:
  - Test under IRIX 6.5.
  - Dynamically switch to 32 bit float as native format when appropriate (let SGI do the conversion), 
    and maybe also the other natively supported formats? (might increase performance)
  - Not sure whether CPU UTILIZATION MEASUREMENT (from OSS/linux) really works. Changed nothing yet,
    seems ok, but I've not yet tested it thoroughly. (maybe utilization-code may be made _unix_common_ then?)
  - The minimal number of buffers setting... I do not yet fully understand it.. I now just take *4.
REFERENCES:
  - IRIX 6.2 man pages regarding SGI AL library.
  - IRIS Digital MediaProgramming Guide (online books as well as man-pages come with IRIX 6.2 and 
    may not be publically available on the internet).
*/

#include <stdio.h>              /* Standard libraries. */
#include <stdlib.h>

#include "../pa_common/portaudio.h"     /* Portaudio headers. */
#include "../pa_common/pa_host.h"
#include "../pa_common/pa_trace.h"

/*
#include <malloc.h>
#include <memory.h>
#include <sys/prctl.h>          Not needed
#include <sys/types.h>
#include <sys/schedctl.h>
#include <signal.h>
#include <sys/ioctl.h>           Needed? 
#include <sys/time.h>
#include <sched.h>               sched_param struct and related functions  
                                 used in setting thread priorities.        
#include <limits.h>              Some POSIX constants such as _POSIX_THREAD_THREADS_MAX
*/

#include <pthread.h>            /* Pthreads are supported by IRIX 6.2 after       */
                                /* patches 1361, 1367, and 1429 are applied.      */
                                
#include <fcntl.h>              /* fcntl.h needed for "O_RDONLY". */
#include <unistd.h>             /* For usleep() and constants used when calling sysconf() */
                                /* to query POSIX limits (see the sysconf(3) ref. page.   */

#include <dmedia/audio.h>       /* SGI-specific audio library.    */


/*--------------------------------------------*/
#define PRINT(x)   { printf x; fflush(stdout); }
#define ERR_RPT(x) PRINT(x)
#define DBUG(x)    PRINT(x)
#define DBUGX(x)   /* PRINT(x) */

#define MAX_CHARS_DEVNAME           (16)        /* Was 32 in OSS (20 for AL but "in"/"out" is concat. */
#define MAX_SAMPLE_RATES            (8)         /* Known from SGI AL there are 7 (was 10 in OSS v15). */

typedef struct                    internalPortAudioDevice                 /* IRIX specific device info:      */
{
  PaDeviceID           /* NEW: */ pad_DeviceID;                           /* THIS "ID" IS NEW HERE (Pieter)! */
  long                            pad_ALdevice;                           /* SGI-number!                     */
  double                          pad_SampleRates[MAX_SAMPLE_RATES];      /* for pointing to from pad_Info   */
  char                            pad_DeviceName[MAX_CHARS_DEVNAME+1];    /* +1 for \0, one more than OSS.   */
  PaDeviceInfo                    pad_Info;                               /* pad_Info (v15) contains:        */
   	                              /* int            structVersion;                                           */
	                              /* const char*    name;                                                    */
	                              /* int            maxInputChannels, maxOutputChannels;                     */
	                              /* int            numSampleRates;       Num rates, or -1 if range supprtd. */
                                  /* const double*  sampleRates;          Array of supported sample rates,   */
	                              /* PaSampleFormat nativeSampleFormats;  or {min,max} if range supported.   */
  struct internalPortAudioDevice* pad_Next;                               /* Singly linked list, (NULL=end). */
} internalPortAudioDevice;

typedef struct      PaHostSoundControl              /* Structure to contain all SGI IRIX specific data. */
{
  ALport            pahsc_ALportIN,                 /* IRIX-audio-library-datatype. ALports can only be */
                    pahsc_ALportOUT;                /* unidirectional, so we sometimes need 2 of them.  */
  pthread_t         pahsc_ThreadPID;
  short             *pahsc_NativeInputBuffer,       /* Allocated here, in this file, if necessary.      */
                    *pahsc_NativeOutputBuffer;
  unsigned int      pahsc_BytesPerInputBuffer,      /* Native buffer sizes in bytes, really needed here */
                    pahsc_BytesPerOutputBuffer;     /* to free FAST memory, if buffs were alloctd FAST. */
  unsigned int      pahsc_SamplesPerInputBuffer,    /* These amounts are needed again and again in the  */
                    pahsc_SamplesPerOutputBuffer;   /* audio-thread (don't need to be kept globally).   */
  struct itimerval  pahsc_EntryTime,                /* For measuring CPU utilization (same as linux).   */
                    pahsc_LastExitTime;
  long              pahsc_InsideCountSum,
                    pahsc_TotalCountSum;
} PaHostSoundControl;

/*----------------------------- Shared Data ------------------------------------------------------*/
static internalPortAudioDevice* sDeviceList = NULL; /* FIXME - put Mutex around this shared data. */
static int                      sPaHostError = 0;   /* Maybe more than one process writing errs!? */

long Pa_GetHostError(void)
{
    return (long)sPaHostError;
}

/*----------------------------- BEGIN CPU UTILIZATION MEASUREMENT -----------------*/
/*                              (copied from source pa_linux_oss/pa_linux_oss.c)   */
static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
{
	struct itimerval itimer;
	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if( pahsc == NULL ) return;
/* Query system timer for usage analysis and to prevent overuse of CPU. */
	getitimer( ITIMER_REAL, &pahsc->pahsc_EntryTime );
}

static long SubtractTime_AminusB( struct itimerval *timeA, struct itimerval *timeB )
{
	long secs = timeA->it_value.tv_sec - timeB->it_value.tv_sec;
	long usecs = secs * 1000000;
	usecs += (timeA->it_value.tv_usec - timeB->it_value.tv_usec);
	return usecs;
}

static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
{
	struct  itimerval currentTime;
	long    insideCount;
	long    totalCount;       /* Measure CPU utilization during this callback. */

#define LOWPASS_COEFFICIENT_0   (0.95)
#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)

	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
	if (pahsc == NULL)
        return;
	if (getitimer( ITIMER_REAL, &currentTime ) == 0 )
	    {
		if (past->past_IfLastExitValid)
		    {
			insideCount = SubtractTime_AminusB( &pahsc->pahsc_EntryTime, &currentTime );
			pahsc->pahsc_InsideCountSum += insideCount;
			totalCount =  SubtractTime_AminusB( &pahsc->pahsc_LastExitTime, &currentTime );
			pahsc->pahsc_TotalCountSum += totalCount;
		/*  DBUG(("insideCount = %d, totalCount = %d\n", insideCount, totalCount )); */
            /* Low pass filter the result because sometimes we get called several times in a row. */
            /* That can cause the TotalCount to be very low which can cause the usage to appear   */
            /* unnaturally high. So we must filter numerator and denominator separately!!!        */
 			if (pahsc->pahsc_InsideCountSum > 0)
			    {
				past->past_AverageInsideCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) +
					                             (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_InsideCountSum));
				past->past_AverageTotalCount  = ((LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) +
					                             (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_TotalCountSum));
				past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount;
				pahsc->pahsc_InsideCountSum = 0;
				pahsc->pahsc_TotalCountSum = 0;
			    }
		    }
		past->past_IfLastExitValid = 1;
	    }
	pahsc->pahsc_LastExitTime.it_value.tv_sec = 100;
	pahsc->pahsc_LastExitTime.it_value.tv_usec = 0;
	setitimer( ITIMER_REAL, &pahsc->pahsc_LastExitTime, NULL );
	past->past_IfLastExitValid = 1;
}   /*----------- END OF CPU UTILIZATION CODE (from pa_linux_oss/pa_linux_oss.c v15)--------------------*/


/*--------------------------------------------------------------------------------------*/
PaError translateSGIerror(void) /* Calls oserror(), may be used after an SGI AL-library */
{                               /* call to report via ERR_RPT(), yields a PaError-num.  */
    const char* a = "SGI AL ";  /* (Not absolutely sure errno came from THIS thread!    */
    switch(oserror())           /* Read IRIX man-pages about the _SGI_MP_SOURCE macro.) */
        {
        case AL_BAD_OUT_OF_MEM:
             ERR_RPT(("%sout of memory.\n", a)); 
             return paInsufficientMemory;                   /* Known PaError.   */
        case AL_BAD_CONFIG:
             ERR_RPT(("%sconfiguration invalid or NULL.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_CHANNELS:
             ERR_RPT(("%schannels not 1,2 or 4.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_NO_PORTS:
             ERR_RPT(("%sout of audio ports.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_DEVICE:
             ERR_RPT(("%swrong device number.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_DEVICE_ACCESS:
             ERR_RPT(("%swrong device access.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_DIRECTION:
             ERR_RPT(("%sinvalid direction.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_SAMPFMT:
             ERR_RPT(("%sdoesn't accept sampleformat.\n", a));
             return paHostError;                            /* Generic PaError. */
        case AL_BAD_FLOATMAX:

⌨️ 快捷键说明

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