gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

blocking_read_write.dox (3428B)


      1 /** @page blocking_read_write Blocking Read/Write Functions
      2 @ingroup tutorial
      3 
      4 PortAudio V19 adds a huge advance over previous versions with a feature called Blocking I/O. Although it may have lower performance that the callback method described earlier in this tutorial, blocking I/O is easier to understand and is, in some cases, more compatible with third party systems than the callback method. Most people starting audio programming also find Blocking I/O easier to learn.
      5 
      6 Blocking I/O works in much the same way as the callback method except that instead of providing a function to provide (or consume) audio data, you must feed data to (or consume data from) PortAudio at regular intervals, usually inside a loop. The example below, excepted from patest_read_write_wire.c, shows how to open the default device, and pass data from its input to its output for a set period of time. Note that we use the default high latency values to help avoid underruns since we are usually reading and writing audio data from a relatively low priority thread, and there is usually extra buffering required to make blocking I/O work.
      7 
      8 Note that not all API's implement Blocking I/O at this point, so for maximum portability or performance, you'll still want to use callbacks.
      9 
     10 @code
     11     /* -- initialize PortAudio -- */
     12     err = Pa_Initialize();
     13     if( err != paNoError ) goto error;
     14 
     15     /* -- setup input and output -- */
     16     inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
     17     inputParameters.channelCount = NUM_CHANNELS;
     18     inputParameters.sampleFormat = PA_SAMPLE_TYPE;
     19     inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
     20     inputParameters.hostApiSpecificStreamInfo = NULL;
     21 
     22     outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
     23     outputParameters.channelCount = NUM_CHANNELS;
     24     outputParameters.sampleFormat = PA_SAMPLE_TYPE;
     25     outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
     26     outputParameters.hostApiSpecificStreamInfo = NULL;
     27 
     28     /* -- setup stream -- */
     29     err = Pa_OpenStream(
     30               &stream,
     31               &inputParameters,
     32               &outputParameters,
     33               SAMPLE_RATE,
     34               FRAMES_PER_BUFFER,
     35               paClipOff,      /* we won't output out of range samples so don't bother clipping them */
     36               NULL, /* no callback, use blocking API */
     37               NULL ); /* no callback, so no callback userData */
     38     if( err != paNoError ) goto error;
     39 
     40     /* -- start stream -- */
     41     err = Pa_StartStream( stream );
     42     if( err != paNoError ) goto error;
     43     printf("Wire on. Will run one minute.\n"); fflush(stdout);
     44 
     45     /* -- Here's the loop where we pass data from input to output -- */
     46     for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
     47     {
     48        err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
     49        if( err ) goto xrun;
     50        err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
     51        if( err ) goto xrun;
     52     }
     53     /* -- Now we stop the stream -- */
     54     err = Pa_StopStream( stream );
     55     if( err != paNoError ) goto error;
     56 
     57     /* -- don't forget to cleanup! -- */
     58     err = Pa_CloseStream( stream );
     59     if( err != paNoError ) goto error;
     60 
     61     Pa_Terminate();
     62     return 0;
     63 @endcode
     64 
     65 
     66 Previous: \ref querying_devices | Next: \ref exploring
     67 
     68 */