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

📄 pa_sgi.c

📁 ppciaxclient softphone
💻 C
📖 第 1 页 / 共 4 页
字号:
            Pa_StartUsageCalculation(past);                         /* Convert 16 bit native data to      */
                                                                    /* user data and call user routine.   */
            inBuffer  = pahsc->pahsc_InputHostBuffer;               /* Short pointers for now, care!      */
            outBuffer = pahsc->pahsc_OutputHostBuffer;
            n = pahsc->pahsc_UserBuffersPerHostBuffer;              /* 'n' may never start at NULL ! */
            do  {
                result = Pa_CallConvertInt16(past, inBuffer, outBuffer);
                if (result)    /* This is apparently NOT an error! Just letting the userCallBack stop us. */
                    { DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result)); goto skip; }
                inBuffer  += samplesPerInputUserBuffer;             /* Num channels is accounted for. */
                outBuffer += samplesPerOutputUserBuffer;
                } while (--n);
            Pa_EndUsageCalculation(past);
            }
        /*------------------------------------ FREE-EVENT FROM OUTPUT BUFFER: ---------------------------*/
        if (pahsc->pahsc_OutputHostBuffer && ioEvent)   /* Don't wait for outputEvent solely (that may cause clicks). */
            {                                           /* Just assume it's time to write, outputEvent may not yet be there. */
            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_OutputHostBuffer,
                             pahsc->pahsc_SamplesPerOutputHostBuffer))
                {
                ERR_RPT(("ALwritesamps() failed.\n"));  /* Better use SEMAS for messaging back to parent! */
                sPaHostError = paInternalError;
                goto skip;
                }
            }
        }
skip:
    /*------------------------------- close AL-ports ----------------------------*/
    if (pahsc->pahsc_ALportIN)
        {
        if (ALcloseport(pahsc->pahsc_ALportIN))
            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))
            translateSGIerror();
        else
            pahsc->pahsc_ALportOUT = (ALport)0;
        }
noPahsc:
    past->past_IsActive = 0;
    if (semaEvent)
        {
        uspsema(SendSema);  /* StopEngine() was still waiting for this acknowledgement. */
        usvsema(RcvSema);   /* (semaEvent initialized with 0.)          */
        }
noPast:
    DBUG(("Leaving sproc-thread.\n"));
}


/*--------------------------------------------------------------------------------------*/
PaError PaHost_OpenStream(internalPortAudioStream *past)
{
    PaError                 result = paNoError;
    PaHostSoundControl      *pahsc;
    unsigned int            minNumBuffers;
    internalPortAudioDevice *padIN, *padOUT;        /* For looking up native AL-numbers. */
    long                    pvbuf[8], sr, alq;      /* To get/set hardware configs.      */

    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 ??                  */
    /*------------------------------------------ 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 both input and output :-) */
    /*-----------------------------------------------------------------------------*/
    /* OVERWRITE 'past_NumUserBuffers'-field in the struct supplied by the caller. */
    /* This field may be set to zero by a client application to ask for minimum    */
    /* latency. It is used below, to set both input- and output-AL-queuesizes.     */    
    minNumBuffers = Pa_GetMinNumBuffers(past->past_FramesPerUserBuffer,
                                        past->past_SampleRate);   /* Take biggest. */   
    past->past_NumUserBuffers = (minNumBuffers > past->past_NumUserBuffers) ? 
                                 minNumBuffers : past->past_NumUserBuffers;
    DBUG(("past->past_NumUserBuffers=%d\n", past->past_NumUserBuffers));
    /*----------------------------------------------------------------------------------*/
    pahsc->pahsc_UserBuffersPerHostBuffer = past->past_NumUserBuffers >> 1;
    DBUG(("pahsc_UserBuffersPerHostBuffer=%d\n",pahsc->pahsc_UserBuffersPerHostBuffer));
    /*  1 is minimum because Pa_GetMinNumBuffers() returns >= 2.
        Callback will be called 'pahsc_UserBuffersPerHostBuffer' times (with 'past_FramesPerUserBuffer')
        per host transfer. */
    /*---------------------------------------------------- SET INPUT CONFIGURATION: ---------------------*/
    if (past->past_NumInputChannels > 0)                                /* We need to lookup the corre-  */
        {                                                               /* sponding native AL-number(s). */
        /*--------------------------------------------------- Allocate native buffers: --------------*/
        pahsc->pahsc_SamplesPerInputHostBuffer = pahsc->pahsc_UserBuffersPerHostBuffer *
                                                 past->past_FramesPerUserBuffer *       /* Needed by the */
                                                 past->past_NumInputChannels;           /* audio-thread. */
        DBUG(("pahsc_SamplesPerInputHostBuffer=%d\n", pahsc->pahsc_SamplesPerInputHostBuffer));
        pahsc->pahsc_BytesPerInputHostBuffer = pahsc->pahsc_SamplesPerInputHostBuffer * sizeof(short);      
        pahsc->pahsc_InputHostBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputHostBuffer);        
        if (!pahsc->pahsc_InputHostBuffer)
            {
            ERR_RPT(("Fast memory allocation failed (in).\n"));
            result = paInsufficientMemory; 
            goto done;
            }
        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 Hz.\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? */
        pahsc->pahsc_ALconfigIN = ALnewconfig();                       /* Released at PaHost_CloseStream().  */
        if (pahsc->pahsc_ALconfigIN == (ALconfig)0)
            goto sgiError;
        if (ALsetsampfmt(pahsc->pahsc_ALconfigIN, AL_SAMPFMT_TWOSCOMP))/* Choose paInt16 as native i/o-format.      */
            goto sgiError;
        if (ALsetwidth (pahsc->pahsc_ALconfigIN, 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(pahsc_ALconfigIN, AL_SAMPFMT_FLOAT))    (Then also call another CallConvert-func.)
            goto sgiError;
        if (ALsetfloatmax (pahsc_ALconfigIN, 1.0))       Only meaningful when sample format for config 
            goto sgiError;                               is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */
        /*--------- Set internal AL queuesize (in samples, not in frames!) -------------------------------*/
        alq = (long)past->past_NumUserBuffers * past->past_FramesPerUserBuffer * past->past_NumInputChannels;
        DBUG(("AL input queuesize = %ld samples.\n", alq));
        if (ALsetqueuesize(pahsc->pahsc_ALconfigIN, alq))
            goto sgiError;
        if (ALsetchannels (pahsc->pahsc_ALconfigIN, (long)(past->past_NumInputChannels)))
            goto sgiError;                              /* Returns 0 on success, -1 on failure. */
        }
    else
        pahsc->pahsc_InputHostBuffer = (short*)NULL;    /* Added 2003! Is checked in callback-routine. */
    /*---------------------------------------------------- SET OUTPUT CONFIGURATION: ------------------------*/
    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. */     
        pahsc->pahsc_SamplesPerOutputHostBuffer = pahsc->pahsc_UserBuffersPerHostBuffer *
                                                  past->past_FramesPerUserBuffer *          /* Needed by the */
                                                  past->past_NumOutputChannels;             /* audio-thread. */
        DBUG(("pahsc_SamplesPerOutputHostBuffer=%d\n", pahsc->pahsc_SamplesPerOutputHostBuffer));
        pahsc->pahsc_BytesPerOutputHostBuffer   = pahsc->pahsc_SamplesPerOutputHostBuffer * sizeof(short);
        pahsc->pahsc_OutputHostBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputHostBuffer);
        if (!pahsc->pahsc_OutputHostBuffer)
            {
            ERR_RPT(("Fast memory allocation failed (out).\n"));
            result = paInsufficientMemory;
            goto done;
            }
        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 (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 Hz.\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;
            }
        pahsc->pahsc_ALconfigOUT = ALnewconfig();                           /* Released at PaHost_CloseStream(). */
        if (pahsc->pahsc_ALconfigOUT == (ALconfig)0)
            goto sgiError;
        if (ALsetsampfmt(pahsc->pahsc_ALconfigOUT, AL_SAMPFMT_TWOSCOMP))    /* Choose paInt16 as native i/o-format. */
            goto sgiError;
        if (ALsetwidth (pahsc->pahsc_ALconfigOUT, 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. **/
        alq = (long)past->past_NumUserBuffers * past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
        DBUG(("AL output queuesize = %ld samples.\n", alq));
        if (ALsetqueuesize(pahsc->pahsc_ALconfigOUT, alq))
            goto sgiError;
        if (ALsetchannels (pahsc->pahsc_ALconfigOUT, (long)(past->past_NumOutputChannels)))
            goto sgiError;
        }
    else
        pahsc->pahsc_OutputHostBuffer = (short*)NULL;
    /*----------------------------------------------- TEST DEVICE ID's: --------------------*/
    if ((past->past_OutputDeviceID != past->past_InputDeviceID) &&          /* Who SETS these devive-numbers? */
        (past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0))
        { 
        ERR_RPT(("Cannot setup bidirectional stream between different devices.\n"));
        result = paHostError;
        goto done;
        }
    goto done;  /* (no errors occured) */
sgiError:   
    result = translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
done:
    if (result != paNoError)
        PaHost_CloseStream(past);               /* Frees memory (only if really allocated!).  */
    return result;
}

/*-----------------------------------------------------*/
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;
    usptr_t             *arena;
    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;            /* Why don't we check pahsc for NULL?   */
    past->past_IsActive = 1;
    
    /* Although the pthread_create() function, as well as <pthread.h>, may be   */
    /* available in IRIX, use sproc() on SGI to create audio-background-thread. */
    /* (Linux/oss uses pthread_create() instead of __clone() because:           */
    /*  - pthread_create also works for other UNIX systems like Solaris,        */
    /*  - Java HotSpot VM crashes in pthread_setcanceltype() using __clone().)  */
    
    usconfig(CONF_ARENATYPE, US_SHAREDONLY);    /* (From SGI-AL-examples, file  */

⌨️ 快捷键说明

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