示例#1
0
signed long GetStreamWriteAvailable( PaStream* stream )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    VVDBUG(("GetStreamWriteAvailable()\n"));

    return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
}
signed long GetStreamReadAvailable( PaStream* stream )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    VVDBUG(("GetStreamReadAvailable()\n"));

    return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer )
                         / ( blio->inputSampleSizeActual * blio->inChan );
}
signed long GetStreamWriteAvailable( PaStream* stream )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    VVDBUG(("GetStreamWriteAvailable()\n"));

    return RingBuffer_GetWriteAvailable( &blio->outputRingBuffer )
                         / ( blio->outputSampleSize * blio->outChan );
}
PaError WriteStream( PaStream* stream,
                            const void *buffer,
                            unsigned long frames )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("WriteStream()\n"));

    while( frames > 0 ) {
       long avail = 0;
       long toWrite;

       do {
          avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
/*
          printf( "Write Buffer is %%%g full: %ld of %ld.\n",
                  100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
                  avail, blio->outputRingBuffer.bufferSize );
*/
          if( avail == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /*block while full*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
             if( ret )
                return ret;
             while( blio->isOutputFull ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( avail == 0 );

       toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan );
       toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ;
       PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite );
       cbuf += toWrite;
       frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan );

#ifdef PA_MAC_BLIO_MUTEX
       if( toWrite == avail ) {
          /* we just filled up the buffer, so we need to mark it as filled. */
          ret = blioSetIsOutputFull( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, we may have emptied the buffer, so
             so check for that, too, to avoid a race condition. */
          if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) {
             blioSetIsOutputFull( blio, false );
             if( ret )
                return ret;
          }
       }
#endif
    }

    /*   Report either paNoError or paOutputUnderflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    ret = blio->statusFlags & paOutputUnderflow;

    /* report underflow only once: */
    if( ret ) {
      OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
      ret = paOutputUnderflowed;
    }

    return ret;
}
PaError ReadStream( PaStream* stream,
                           void *buffer,
                           unsigned long frames )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("ReadStream()\n"));

    while( frames > 0 ) {
       long avail;
       long toRead;
       do {
          avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
/*
          printf( "Read Buffer is %%%g full: %ld of %ld.\n",
                  100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
                  avail, blio->inputRingBuffer.bufferSize );
*/
          if( avail == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /**block when empty*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
             if( ret )
                return ret;
             while( blio->isInputEmpty ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( avail == 0 );
       toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan );
       toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ;
       PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead );
       cbuf += toRead;
       frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan );

       if( toRead == avail ) {
#ifdef PA_MAC_BLIO_MUTEX
          /* we just emptied the buffer, so we need to mark it as empty. */
          ret = blioSetIsInputEmpty( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, the callback may have put some sats
             in, so
             so check for that, too, to avoid a race condition. */
          if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) {
             blioSetIsInputEmpty( blio, false );
             if( ret )
                return ret;
          }
#endif
       }
    }

    /*   Report either paNoError or paInputOverflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    ret = blio->statusFlags & paInputOverflow;

    /* report underflow only once: */
    if( ret ) {
       OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags );
       ret = paInputOverflowed;
    }

    return ret;
}
示例#6
0
PaError WriteStream( PaStream* stream,
                            const void *buffer,
                            unsigned long framesRequested )
{
    PaMacCoreStream *macStream = (PaMacCoreStream*)stream;
    PaMacBlio *blio = &macStream->blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("WriteStream()\n"));

    while( framesRequested > 0 && macStream->state != STOPPING ) {
        ring_buffer_size_t framesAvailable;
        ring_buffer_size_t framesToTransfer;
        ring_buffer_size_t framesTransferred;

       do {
          framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
/*
          printf( "Write Buffer is %%%g full: %ld of %ld.\n",
                  100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
                  framesAvailable, blio->outputRingBuffer.bufferSize );
*/
          if( framesAvailable == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /*block while full*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
             if( ret )
                return ret;
             while( blio->isOutputFull ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( framesAvailable == 0 && macStream->state != STOPPING );

       if( macStream->state == STOPPING )
       {
           break;
       }

       framesToTransfer = MIN( framesAvailable, framesRequested );
       framesTransferred = PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer );
       cbuf += framesTransferred * blio->outputSampleSizeActual * blio->outChan;
       framesRequested -= framesTransferred;

#ifdef PA_MAC_BLIO_MUTEX
       if( framesToTransfer == framesAvailable ) {
          /* we just filled up the buffer, so we need to mark it as filled. */
          ret = blioSetIsOutputFull( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, we may have emptied the buffer, so
             so check for that, too, to avoid a race condition. */
          if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) {
             blioSetIsOutputFull( blio, false );
              /* FIXME remove or review this code, does not fix race, ret not set! */
             if( ret )
                return ret;
          }
       }
#endif
    }

    if ( macStream->state == STOPPING )
    {
        ret = paInternalError;
    }
    else if (ret == paNoError )
    {
        /*   Test for underflow. */
        ret = blio->statusFlags & paOutputUnderflow;

        /* report underflow only once: */
        if( ret )
        {
            OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
            ret = paOutputUnderflowed;
        }
    }

    return ret;
}
示例#7
0
PaError ReadStream( PaStream* stream,
                           void *buffer,
                           unsigned long framesRequested )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("ReadStream()\n"));

    while( framesRequested > 0 ) {
       ring_buffer_size_t framesAvailable;
       ring_buffer_size_t framesToTransfer;
       ring_buffer_size_t framesTransferred;
       do {
          framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
/*
          printf( "Read Buffer is %%%g full: %ld of %ld.\n",
                  100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
                  framesAvailable, blio->inputRingBuffer.bufferSize );
*/
          if( framesAvailable == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /**block when empty*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
             if( ret )
                return ret;
             while( blio->isInputEmpty ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( framesAvailable == 0 );
       framesToTransfer = (ring_buffer_size_t) MIN( framesAvailable, framesRequested );
       framesTransferred = PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer );
       cbuf += framesTransferred * blio->inputSampleSizeActual * blio->inChan;
       framesRequested -= framesTransferred;

       if( framesToTransfer == framesAvailable ) {
#ifdef PA_MAC_BLIO_MUTEX
          /* we just emptied the buffer, so we need to mark it as empty. */
          ret = blioSetIsInputEmpty( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, the callback may have put some sats
             in, so
             so check for that, too, to avoid a race condition. */
          /* FIXME - this does not seem to fix any race condition. */
          if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) {
             blioSetIsInputEmpty( blio, false );
             /* FIXME - why check? ret has not been set? */
             if( ret )
                return ret;
          }
#endif
       }
    }

    /*   Report either paNoError or paInputOverflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    /* FIXME should not clobber ret, use if(blio->statusFlags & paInputOverflow) */
    ret = blio->statusFlags & paInputOverflow;

    /* report underflow only once: */
    if( ret ) {
       OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags );
       ret = paInputOverflowed;
    }

    return ret;
}