Пример #1
0
    /* callback for "non-callback" case where we communicate with the
    main thread via FIFO.  Here we first read the sudio output FIFO (which
    we sync on, not waiting for it but supplying zeros to the audio output if
    there aren't enough samples in the FIFO when we are called), then write
    to the audio input FIFO.  The main thread will wait for the input fifo.
    We can either throw it a pthreads condition or just allow the main thread
    to poll for us; so far polling seems to work better. */
static int pa_fifo_callback(const void *inputBuffer,
    void *outputBuffer, unsigned long nframes,
    const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags myflags, 
    void *userData)
{
    /* callback routine for non-callback client... throw samples into
            and read them out of a FIFO */
    int ch;
    long fiforoom;
    float *fbuf;

#if CHECKFIFOS
    if (pa_inchans * sys_ringbuf_GetReadAvailable(&pa_outring) !=   
        pa_outchans * sys_ringbuf_GetWriteAvailable(&pa_inring))
            fprintf(stderr, "warning: in and out rings unequal (%d, %d)\n",
                sys_ringbuf_GetReadAvailable(&pa_outring),
                 sys_ringbuf_GetWriteAvailable(&pa_inring));
#endif
    fiforoom = sys_ringbuf_GetReadAvailable(&pa_outring);
    if ((unsigned)fiforoom >= nframes*pa_outchans*sizeof(float))
    {
        if (outputBuffer)
            sys_ringbuf_Read(&pa_outring, outputBuffer,
                nframes*pa_outchans*sizeof(float));
        else if (pa_outchans)
            fprintf(stderr, "no outputBuffer but output channels\n");
        if (inputBuffer)
            sys_ringbuf_Write(&pa_inring, inputBuffer,
                nframes*pa_inchans*sizeof(float));
        else if (pa_inchans)
            fprintf(stderr, "no inputBuffer but input channels\n");
    }
    else
    {        /* PD could not keep up; generate zeros */
        if (pa_started)
            pa_dio_error = 1;
        if (outputBuffer)
        {
            for (ch = 0; ch < pa_outchans; ch++)
            {
                unsigned long frame;
                fbuf = ((float *)outputBuffer) + ch;
                for (frame = 0; frame < nframes; frame++, fbuf += pa_outchans)
                    *fbuf = 0;
            }
        }
    }
#ifdef THREADSIGNAL
    pthread_mutex_lock(&pa_mutex);
    pthread_cond_signal(&pa_sem);
    pthread_mutex_unlock(&pa_mutex);
#endif
    return 0;
}
Пример #2
0
int pa_send_dacs(void)
{
    t_sample *fp;
    float *fp2, *fp3;
    float *conversionbuf;
    int j, k;
    int rtnval =  SENDDACS_YES;
    int timenow;
    int timeref = sys_getrealtime();
    if (!sys_inchannels && !sys_outchannels)
        return (SENDDACS_NO); 
#if CHECKFIFOS
    if (sys_outchannels * sys_ringbuf_GetReadAvailable(&pa_inring) !=   
        sys_inchannels * sys_ringbuf_GetWriteAvailable(&pa_outring))
            fprintf(stderr, "warning (2): in and out rings unequal  (%d, %d)\n",
                sys_ringbuf_GetReadAvailable(&pa_inring),
                    sys_ringbuf_GetWriteAvailable(&pa_outring));
#endif
    conversionbuf = (float *)alloca((sys_inchannels > sys_outchannels?
        sys_inchannels:sys_outchannels) * DEFDACBLKSIZE * sizeof(float));
    if (pa_dio_error)
    {
        sys_log_error(ERR_RESYNC);
        pa_dio_error = 0;
    }

    if (!sys_inchannels)    /* if no input channels sync on output */
    {
#ifdef THREADSIGNAL
        pthread_mutex_lock(&pa_mutex);
#endif
        while (sys_ringbuf_GetWriteAvailable(&pa_outring) <
            (long)(sys_outchannels * DEFDACBLKSIZE * sizeof(float)))
#ifdef THREADSIGNAL
                pthread_cond_wait(&pa_sem, &pa_mutex);
#else
#ifdef _WIN32
                Sleep(1);
#else
                usleep(1000);
#endif /* _WIN32 */
#endif /* THREADSIGNAL */
#ifdef THREADSIGNAL
        pthread_mutex_unlock(&pa_mutex);
#endif
    }
        /* write output */
    if (sys_outchannels)
    {
        for (j = 0, fp = sys_soundout, fp2 = conversionbuf;
            j < sys_outchannels; j++, fp2++)
                for (k = 0, fp3 = fp2; k < DEFDACBLKSIZE;
                    k++, fp++, fp3 += sys_outchannels)
                        *fp3 = *fp;
        sys_ringbuf_Write(&pa_outring, conversionbuf,
            sys_outchannels*(DEFDACBLKSIZE*sizeof(float)));
    }
    if (sys_inchannels)    /* if there is input sync on it */
    {
#ifdef THREADSIGNAL
        pthread_mutex_lock(&pa_mutex);
#endif
        while (sys_ringbuf_GetReadAvailable(&pa_inring) <
            (long)(sys_inchannels * DEFDACBLKSIZE * sizeof(float)))
#ifdef THREADSIGNAL
                pthread_cond_wait(&pa_sem, &pa_mutex);
#else
#ifdef _WIN32
                Sleep(1);
#else
                usleep(1000);
#endif /* _WIN32 */
#endif /* THREADSIGNAL */
#ifdef THREADSIGNAL
        pthread_mutex_unlock(&pa_mutex);
#endif
    }
    pa_started = 1;

    if (sys_inchannels)
    {
        sys_ringbuf_Read(&pa_inring, conversionbuf,
            sys_inchannels*(DEFDACBLKSIZE*sizeof(float)));
        for (j = 0, fp = sys_soundin, fp2 = conversionbuf;
            j < sys_inchannels; j++, fp2++)
                for (k = 0, fp3 = fp2; k < DEFDACBLKSIZE;
                    k++, fp++, fp3 += sys_inchannels)
                        *fp = *fp3;
    }

    if ((timenow = sys_getrealtime()) - timeref > 0.002)
    {
        rtnval = SENDDACS_SLEPT;
    }
    memset(sys_soundout, 0, DEFDACBLKSIZE*sizeof(t_sample)*sys_outchannels);
    return rtnval;
}
Пример #3
0
/************************************************************
 * Return the number of frames that are available to be read from the
 * stream without having to wait.
 */
long GetAudioStreamReadable( PABLIO_Stream *aStream )
{
    int bytesFull = sys_ringbuf_GetReadAvailable( &aStream->inFIFO );
    return bytesFull / aStream->inbytesPerFrame;
}