Exemple #1
0
/* Called from PortAudio.
 * Read and write data only if there is room in FIFOs.
 */
static int blockingIOCallback( const void *inputBuffer, void *outputBuffer, /* MSP */
                               unsigned long framesPerBuffer,
                               const PaStreamCallbackTimeInfo *outTime, 
                               PaStreamCallbackFlags myflags, 
                               void *userData )
{
    PABLIO_Stream *data = (PABLIO_Stream*)userData;
    (void) outTime;

    /* This may get called with NULL inputBuffer during initial setup. */
    if( inputBuffer != NULL )
    {
        sys_ringbuf_Write( &data->inFIFO, inputBuffer,
            data->inbytesPerFrame * framesPerBuffer );
    }
    if( outputBuffer != NULL )
    {
        int i;
        int numBytes = data->outbytesPerFrame * framesPerBuffer;
        int numRead = sys_ringbuf_Read( &data->outFIFO, outputBuffer,
            numBytes);
        /* Zero out remainder of buffer if we run out of data. */
        for( i=numRead; i<numBytes; i++ )
        {
            ((char *)outputBuffer)[i] = 0;
        }
    }

    return 0;
}
Exemple #2
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;
}
Exemple #3
0
/************************************************************
 * Write data to ring buffer.
 * Will not return until all the data has been written.
 */
long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
{
    long bytesWritten;
    char *p = (char *) data;
    long numBytes = aStream->outbytesPerFrame * numFrames;
    while( numBytes > 0)
    {
        bytesWritten = sys_ringbuf_Write( &aStream->outFIFO, p, numBytes );
        numBytes -= bytesWritten;
        p += bytesWritten;
        if( numBytes > 0) NPa_Sleep(10); /* MSP */
    }
    return numFrames;
}
Exemple #4
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;
}