/******************************************/ /* duplex.cpp by Gary P. Scavone, 2006-2007. This program opens a duplex stream and passes input directly through to the output. */ /******************************************/ #include "RtAudio.h" #include #include #include /* typedef signed long MY_TYPE; #define FORMAT RTAUDIO_SINT24 typedef char MY_TYPE; #define FORMAT RTAUDIO_SINT8 */ typedef signed short MY_TYPE; #define FORMAT RTAUDIO_SINT16 /* typedef signed long MY_TYPE; #define FORMAT RTAUDIO_SINT32 typedef float MY_TYPE; #define FORMAT RTAUDIO_FLOAT32 typedef double MY_TYPE; #define FORMAT RTAUDIO_FLOAT64 */ void usage( void ) { // Error function in case of incorrect command-line // argument specifications std::cout << "\nuseage: duplex N fs \n"; std::cout << " where N = number of channels,\n"; std::cout << " fs = the sample rate,\n"; std::cout << " iDevice = optional input device to use (default = 0),\n"; std::cout << " oDevice = optional output device to use (default = 0),\n"; std::cout << " iChannelOffset = an optional input channel offset (default = 0),\n"; std::cout << " and oChannelOffset = optional output channel offset (default = 0).\n\n"; exit( 0 ); } int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *data ) { // Since the number of input and output channels is equal, we can do // a simple buffer copy operation here. if ( status ) std::cout << "Stream over/underflow detected." << std::endl; unsigned int *bytes = (unsigned int *) data; memcpy( outputBuffer, inputBuffer, *bytes ); return 0; } int main( int argc, char *argv[] ) { unsigned int channels, fs, bufferBytes, oDevice = 0, iDevice = 0, iOffset = 0, oOffset = 0; // Minimal command-line checking if (argc < 3 || argc > 7 ) usage(); RtAudio adac; if ( adac.getDeviceCount() < 1 ) { std::cout << "\nNo audio devices found!\n"; exit( 1 ); } channels = (unsigned int) atoi(argv[1]); fs = (unsigned int) atoi(argv[2]); if ( argc > 3 ) iDevice = (unsigned int) atoi(argv[3]); if ( argc > 4 ) oDevice = (unsigned int) atoi(argv[4]); if ( argc > 5 ) iOffset = (unsigned int) atoi(argv[5]); if ( argc > 6 ) oOffset = (unsigned int) atoi(argv[6]); // Let RtAudio print messages to stderr. adac.showWarnings( true ); // Set the same number of channels for both input and output. unsigned int bufferFrames = 512; RtAudio::StreamParameters iParams, oParams; iParams.deviceId = iDevice; iParams.nChannels = channels; iParams.firstChannel = iOffset; oParams.deviceId = oDevice; oParams.nChannels = channels; oParams.firstChannel = oOffset; RtAudio::StreamOptions options; //options.flags |= RTAUDIO_NONINTERLEAVED; try { adac.openStream( &oParams, &iParams, FORMAT, fs, &bufferFrames, &inout, (void *)&bufferBytes, &options ); } catch ( RtError& e ) { std::cout << '\n' << e.getMessage() << '\n' << std::endl; exit( 1 ); } bufferBytes = bufferFrames * channels * sizeof( MY_TYPE ); // Test RtAudio functionality for reporting latency. std::cout << "\nStream latency = " << adac.getStreamLatency() << " frames" << std::endl; try { adac.startStream(); char input; std::cout << "\nRunning ... press to quit (buffer frames = " << bufferFrames << ").\n"; std::cin.get(input); // Stop the stream. adac.stopStream(); } catch ( RtError& e ) { std::cout << '\n' << e.getMessage() << '\n' << std::endl; goto cleanup; } cleanup: if ( adac.isStreamOpen() ) adac.closeStream(); return 0; }