/* This should be called after stopping or aborting the stream, so that on next
   start, the buffers will be ready. */
PaError resetBlioRingBuffers( PaMacBlio *blio )
{
#ifdef PA_MAC__BLIO_MUTEX
   int result;
#endif
   blio->statusFlags = 0;
   if( blio->outputRingBuffer.buffer ) {
      RingBuffer_Flush( &blio->outputRingBuffer );
      bzero( blio->outputRingBuffer.buffer,
             blio->outputRingBuffer.bufferSize );
      /* Advance buffer */
      RingBuffer_AdvanceWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize );

      /* Update isOutputFull. */
#ifdef PA_MAC__BLIO_MUTEX
      result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize );
      if( result )
         goto error;
#endif
/*
      printf( "------%d\n" ,  blio->framesPerBuffer );
      printf( "------%d\n" ,  blio->outChan );
      printf( "------%d\n" ,  blio->outputSampleSize );
      printf( "------%d\n" ,  blio->framesPerBuffer*blio->outChan*blio->outputSampleSize );
*/
   }
   if( blio->inputRingBuffer.buffer ) {
      RingBuffer_Flush( &blio->inputRingBuffer );
      bzero( blio->inputRingBuffer.buffer,
             blio->inputRingBuffer.bufferSize );
      /* Update isInputEmpty. */
#ifdef PA_MAC__BLIO_MUTEX
      result = blioSetIsInputEmpty( blio, true );
      if( result )
         goto error;
#endif
   }
   return paNoError;
#ifdef PA_MAC__BLIO_MUTEX
 error:
   return result;
#endif
}
Beispiel #2
0
/***************************************************************************
** Return bytes written. */
long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes )
{
    long size1, size2, numWritten;
    void *data1, *data2;
    numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
    if( size2 > 0 )
    {

        memcpy( data1, data, size1 );
        data = ((char *)data) + size1;
        memcpy( data2, data, size2 );
    }
    else
    {
        memcpy( data1, data, size1 );
    }
    RingBuffer_AdvanceWriteIndex( rbuf, numWritten );
    return numWritten;
}
Beispiel #3
0
/************************************************************
 * Opens a PortAudio stream with default characteristics.
 * Allocates PABLIO_Stream structure.
 *
 * flags parameter can be an ORed combination of:
 *    PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE
 */
PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate,
                         PaSampleFormat format, int inchannels,
                         int outchannels, int framesperbuf, int nbuffers,
                         int indeviceno, int outdeviceno) /* MSP */
{
    long   bytesPerSample;
    long   doRead = 0;
    long   doWrite = 0;
    PaError err;
    PABLIO_Stream *aStream;
    long   minNumBuffers; 
    long   numFrames;

//#ifdef PA19
//    PaStreamParameters instreamparams, outstreamparams;  /* MSP */
//#endif

    /* fprintf(stderr,
        "open %lf fmt %d flags %d ch: %d fperbuf: %d nbuf: %d devs: %d %d\n",
           sampleRate, format, flags, nchannels,
           framesperbuf, nbuffers, indeviceno, outdeviceno); */

    if (indeviceno < 0)  /* MSP... */
    {

//#ifdef PA19
//        indeviceno = Pa_GetDefaultInputDevice();
//#else
        indeviceno = Pa_GetDefaultInputDeviceID();
//#endif
        fprintf(stderr, "using default input device number: %d\n", indeviceno);
    }
    if (outdeviceno < 0)
    {

//#ifdef PA19
//        outdeviceno = Pa_GetDefaultOutputDevice();
//#else
        outdeviceno = Pa_GetDefaultOutputDeviceID();
//#endif
        fprintf(stderr, "using default output device number: %d\n", outdeviceno);
    }
    /* fprintf(stderr, "nchan %d, flags %d, bufs %d, framesperbuf %d\n",
            nchannels, flags, nbuffers, framesperbuf); */
        /* ...MSP */

    /* Allocate PABLIO_Stream structure for caller. */
    aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
    if( aStream == NULL ) return paInsufficientMemory;
    memset( aStream, 0, sizeof(PABLIO_Stream) );

    /* Determine size of a sample. */
    bytesPerSample = Pa_GetSampleSize( format );
    if( bytesPerSample < 0 )
    {
        fprintf(stderr, "error bytes per sample: %i\n", bytesPerSample);	
		err = (PaError) bytesPerSample;
        goto error;
    }
    aStream->insamplesPerFrame = inchannels;  /* MSP */
    aStream->inbytesPerFrame = bytesPerSample * aStream->insamplesPerFrame;
    aStream->outsamplesPerFrame = outchannels;
    aStream->outbytesPerFrame = bytesPerSample * aStream->outsamplesPerFrame;

    /* Initialize PortAudio  */
    err = Pa_Initialize();
    if( err != paNoError ) goto error;


//#ifdef PA19
//    numFrames = nbuffers * framesperbuf; /* ...MSP */

//    instreamparams.device = indeviceno;   /* MSP... */
//    instreamparams.channelCount = inchannels;
//    instreamparams.sampleFormat = format;
//    instreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate;
//    instreamparams.hostApiSpecificStreamInfo = 0;
    
//    outstreamparams.device = outdeviceno;
//    outstreamparams.channelCount = outchannels;
//    outstreamparams.sampleFormat = format;
//    outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate;
//   outstreamparams.hostApiSpecificStreamInfo = 0;  /* ... MSP */

//#else
/* Warning: numFrames must be larger than amount of data processed per
  interrupt inside PA to prevent glitches. */  /* MSP */
    minNumBuffers = Pa_GetMinNumBuffers(framesperbuf, sampleRate);
    if (minNumBuffers > nbuffers)
        fprintf(stderr, "warning: number of buffers %d less than recommended minimum %d\n",  (int)nbuffers, (int)minNumBuffers);
//#endif

    numFrames = nbuffers * framesperbuf;
    /* fprintf(stderr, "numFrames %d\n", numFrames); */
    /* Initialize Ring Buffers */
    doRead = (inchannels != 0);
    doWrite = (outchannels != 0);
    if(doRead)
    {
        err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->inbytesPerFrame );
        if( err != paNoError )
		{
			fprintf(stderr, "error doRead PABLIO_InitFIFO \n");
			goto error;
		}
    }
    if(doWrite)
    {
        long numBytes;
        err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->outbytesPerFrame );
        if( err != paNoError ) {
			fprintf(stderr, "error doWrite PABLIO_InitFIFO \n");
			goto error;
			}
        /* Make Write FIFO appear full initially. */
        numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
        RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes );
    }

    /* Open a PortAudio stream that we will use to communicate with the underlying
     * audio drivers. */

//#ifdef PA19
 //   err = Pa_OpenStream(
//              &aStream->stream,
//              (doRead ? &instreamparams : 0),  /* MSP */
//              (doWrite ? &outstreamparams : 0),  /* MSP */
//             sampleRate,
 //             framesperbuf,  /* MSP */
 //             paNoFlag,      /* MSP -- portaudio will clip for us */
 //             blockingIOCallback,
//              aStream );
//#else
 //   err = Pa_OpenStream(
 //             &aStream->stream,
//              (doRead ? indeviceno : paNoDevice),  /* MSP */
//              (doRead ? aStream->insamplesPerFrame : 0 ),
//              format,
//              NULL,
//              (doWrite ? outdeviceno : paNoDevice),  /* MSP */
//              (doWrite ? aStream->outsamplesPerFrame : 0 ),
//              format,
//              NULL,
//              sampleRate,
//              framesperbuf,  /* MSP */
//              nbuffers,      /* MSP */
//              paNoFlag,      /* MSP -- portaudio will clip for us */
//              blockingIOCallback,
//              aStream );
// #endif
PortAudioStream   *stream;
err = Pa_OpenDefaultStream( 
	stream, 
	0,
	2, 
	paFloat32, 
	44100,  
	256, 
	0,  
	blockingIOCallback, 
	stream );


    if( err != paNoError ){
		fprintf(stderr, "error Pa_OpenStream \n");
		goto error;
	}
	
    err = Pa_StartStream( aStream->stream );
    if( err != paNoError )      /* MSP */
    {
        fprintf(stderr, "Pa_StartStream failed; closing audio stream...\n");
        CloseAudioStream( aStream );
        goto error;
    }

    *rwblPtr = aStream;
    return paNoError;

error:
    *rwblPtr = NULL;
    return err;
}