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 */