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

📄 pthread-pa_sgi.c

📁 ppciaxclient softphone
💻 C
📖 第 1 页 / 共 4 页
字号:
	    Pa_EndUsageCalculation(past);
	    if (result) 
		    {
			DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result));
            goto done;                      /* This is apparently NOT an error!       */
		    }                               /* Just letting the userCallBack stop us. */
        /*---------------------------------------- OUTPUT: ------------------------------------*/
        if (pahsc->pahsc_NativeOutputBuffer)    /* Then pahsc_ALportOUT should also be there!  */
            {
            while (ALgetfillable(pahsc->pahsc_ALportOUT) < pahsc->pahsc_SamplesPerOutputBuffer)
                {
                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
                if (past->past_StopNow)    /* Don't let ALwritesamps() block */
                    goto done;
                }
            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer,
                             pahsc->pahsc_SamplesPerOutputBuffer))
                {
                ERR_RPT(("ALwritesamps() failed.\n"));
                result = paInternalError;
                goto done;
                }
            }
        /*-------------------------------------------------------------------------------------*/
        }
done:
    /* pahsc->pahsc_ThreadPID = -1;   Hu? doesn't help!! (added by Pieter) */
    past->past_IsActive = 0;
    DBUG(("leaving thread.\n"));
    return result;
}


/*--------------------------------------------------------------------------------------*/
PaError PaHost_OpenStream(internalPortAudioStream *past)
{
	PaError                 result = paNoError;
	PaHostSoundControl      *pahsc;
	unsigned int            minNumBuffers;
	internalPortAudioDevice *padIN, *padOUT;        /* For looking up native AL-numbers. */
    ALconfig                sgiALconfig = NULL;     /* IRIX-datatype.   */
    long                    pvbuf[8];               /* To get/set hardware configs.      */
    long                    sr, ALqsize;
    DBUG(("PaHost_OpenStream() called.\n"));        /* Alloc FASTMEM and init host data. */
    if (!past)
        {
        ERR_RPT(("Streampointer NULL!\n"));
        result = paBadStreamPtr;        goto done;
        }
	pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
	if (pahsc == NULL)
	    {
        ERR_RPT(("FAST Memory allocation failed.\n"));  /* Pass trough some ERR_RPT-exit-  */
        result = paInsufficientMemory;  goto done;      /* code (nothing will be freed).   */
	    }
	memset(pahsc, 0, sizeof(PaHostSoundControl));
/*  pahsc->pahsc_threadPID = -1;                       Should pahsc_threadPID be inited to */
	past->past_DeviceData = (void*)pahsc;           /* -1 instead of 0 ??                  */
    /*--------------------------------------------------- Allocate native buffers: --------*/
    pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
                                         past->past_NumInputChannels;     /* audio-thread. */
	pahsc->pahsc_BytesPerInputBuffer   = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short);
	if (past->past_NumInputChannels > 0)                       /* Assumes short = 16 bits! */
	    {
		pahsc->pahsc_NativeInputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputBuffer);        
		if( pahsc->pahsc_NativeInputBuffer == NULL )
		    {
            ERR_RPT(("Fast memory allocation for input-buffer failed.\n"));
			result = paInsufficientMemory;  goto done;
		    }
	    }
    pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
                                          past->past_NumOutputChannels;    /* audio-thread. */
	pahsc->pahsc_BytesPerOutputBuffer   = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short);
	if (past->past_NumOutputChannels > 0)                       /* Assumes short = 16 bits! */
	    {
		pahsc->pahsc_NativeOutputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputBuffer);
		if (pahsc->pahsc_NativeOutputBuffer == NULL)
		    {
            ERR_RPT(("Fast memory allocation for output-buffer failed.\n"));
			result = paInsufficientMemory;  goto done;
		    }
	    }
    /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/
    ALseterrorhandler(0);                           /* 0 = turn off the default error handler.   */
    pvbuf[0] = AL_INPUT_RATE;
    pvbuf[2] = AL_INPUT_COUNT;
    pvbuf[4] = AL_OUTPUT_RATE;              /* TO FIX: rates may be logically, not always in Hz! */
    pvbuf[6] = AL_OUTPUT_COUNT;
    sr = (long)(past->past_SampleRate + 0.5);   /* Common for input and output :-)               */
    if (past->past_NumInputChannels > 0)                        /* We need to lookup the corre-  */
        {                                                       /* sponding native AL-number(s). */
        padIN = Pa_GetInternalDevice(past->past_InputDeviceID);
        if (!padIN)
            {
            ERR_RPT(("Pa_GetInternalDevice() for input failed.\n"));
	        result = paHostError;  goto done;
            }
        if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */
            goto sgiError;                                  /* the same AL-device, the AL-library might  */
        if (pvbuf[1] != sr)                                 /* contain more than AL_DEFAULT_DEVICE in    */
            {  /* Rate different from current harware-rate?    the future. Therefore 2 seperate queries. */
            if (pvbuf[3] > 0)     /* Means, there's other clients using AL-input-ports */
                {
                ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \
another process is currently using input at %ld kHz.\n", sr, pvbuf[1]));
                result = paHostError;   goto done;
                }
            pvbuf[1] = sr;                  /* Then set input-rate. */
            if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2))
                goto sgiError;      /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */
            }                       /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */
        }
    if (past->past_NumOutputChannels > 0)           /* CARE: padOUT/IN may NOT be NULL if Channels <= 0! */
        {                                           /* We use padOUT/IN later on, or at least 1 of both. */
        padOUT = Pa_GetInternalDevice(past->past_OutputDeviceID);
        if (!padOUT)
            {
            ERR_RPT(("Pa_GetInternalDevice() for output failed.\n"));
	        result = paHostError;  goto done;
            }
        if (ALgetparams(padOUT->pad_ALdevice,&pvbuf[4], 4))
            goto sgiError;
        if ((past->past_NumOutputChannels > 0) && (pvbuf[5] != sr))
            {   /* Output needed and rate different from current harware-rate. */
            if (pvbuf[7] > 0)     /* Means, there's other clients using AL-output-ports */
                {
                ERR_RPT(("Sorry, not allowed to switch output-hardware to %ld Hz because \
another process is currently using output at %ld kHz.\n", sr, pvbuf[5]));            
                result = paHostError;   goto done;      /* Will free again the inputbuffer */
                }                                       /* that was just created above.    */
            pvbuf[5] = sr;                  /* Then set output-rate. */
            if (ALsetparams(padOUT->pad_ALdevice, &pvbuf[4], 2))
                goto sgiError;
            }
        }
    /*------------------------------------------ Construct an audio-port-configuration ----------*/
    sgiALconfig = ALnewconfig();                    /* Change the SGI-AL-default-settings.       */
    if (sgiALconfig == (ALconfig)0)                 /* sgiALconfig is released here after use!   */
        goto sgiError;                              /* See that sgiALconfig is NOT released!     */
    if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_TWOSCOMP))  /* Choose paInt16 as native i/o-format. */
        goto sgiError;
    if (ALsetwidth (sgiALconfig, AL_SAMPLE_16))     /* Only meaningful when sample format for    */
        goto sgiError;                              /* config is set to two's complement format. */
    /************************ Future versions might (dynamically) switch to 32-bit floats? *******
    if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_FLOAT))    (Then also call another CallConvert-func.)
        goto sgiError;
    if (ALsetfloatmax (sgiALconfig, 1.0))       Only meaningful when sample format for config 
        goto sgiError;                          is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */
    /*---------- ?? --------------------*/
	/* 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;
    /*------------------------------------------------ Set internal AL queuesize (in samples) ----*/
    if (pahsc->pahsc_SamplesPerInputBuffer >= pahsc->pahsc_SamplesPerOutputBuffer)
        ALqsize = (long)pahsc->pahsc_SamplesPerInputBuffer;
    else                                            /* Take the largest of the two amounts.       */
        ALqsize = (long)pahsc->pahsc_SamplesPerOutputBuffer;
    ALqsize *= 4;                                   /* 4 times as large as amount per transfer!   */    
    if (ALsetqueuesize(sgiALconfig, ALqsize))       /* Or should we use past_NumUserBuffers here? */
        goto sgiError;                              /* Using 2 times may give glitches... */
    /* Have to work on ALsetqueuesize() above. */

    /* Do ALsetchannels() later, apart per input and/or output. */
    /*----------------------------------------------- OPEN 1 OR 2 AL-DEVICES: --------------------*/
	if (past->past_OutputDeviceID == past->past_InputDeviceID)  /* Who SETS these devive-numbers? */
	    {
		if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0))
		    {
            DBUG(("PaHost_OpenStream: opening both input and output channels.\n"));
            /*------------------------- open output port: ----------------------------------*/
            if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels)))
                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
            pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig);
            if (pahsc->pahsc_ALportOUT == (ALport)0)
                goto sgiError;
            /*------------------------- open input port: -----------------------------------*/
            if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels)))
                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
            pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig);
            if (pahsc->pahsc_ALportIN == (ALport)0)
                goto sgiError;          /* For some reason the "patest_wire.c"-test crashes! */
		    }                           /* Probably due to too small buffersizes?....        */
        else
            {
            ERR_RPT(("Cannot setup bidirectional stream between different devices.\n"));
            result = paHostError;
            goto done;
            }
	    }
	else /* (OutputDeviceID != InputDeviceID) */
	    {
		if (past->past_NumOutputChannels > 0)   /* WRITE-ONLY: */
		    {	    
            /*------------------------- open output port: ----------------------------------*/
            DBUG(("PaHost_OpenStream: opening %d output channel(s) on %s.\n",
                 past->past_NumOutputChannels, padOUT->pad_DeviceName));
            if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels)))
                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
            pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig);
            if (pahsc->pahsc_ALportOUT == (ALport)0)
                goto sgiError;
		    }
		if (past->past_NumInputChannels > 0)   /* READ-ONLY: */
		    {	    
            /*------------------------- open input port: -----------------------------------*/
            DBUG(("PaHost_OpenStream: opening %d input channel(s) on %s.\n",
                 past->past_NumInputChannels, padIN->pad_DeviceName));
            if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels)))
                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
            pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig);
            if (pahsc->pahsc_ALportIN == (ALport)0)
                goto sgiError;
		    }
	    }
	DBUG(("PaHost_OpenStream() succeeded.\n"));
    goto done;  /* (no errors occured) */
sgiError:   
    result = translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
done:
    if (sgiALconfig)
        ALfreeconfig(sgiALconfig);              /* We don't need that struct anymore. */
    if (result != paNoError)
        PaHost_CloseStream(past);               /* Frees memory (only if really allocated!).  */
    return result;
}

⌨️ 快捷键说明

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