Various changes in preparation for release 4.0.8
[rtaudio-cdist.git] / tests / duplex.cpp
1 /******************************************/
2 /*
3   duplex.cpp
4   by Gary P. Scavone, 2006-2007.
5
6   This program opens a duplex stream and passes
7   input directly through to the output.
8 */
9 /******************************************/
10
11 #include "RtAudio.h"
12 #include <iostream>
13 #include <cstdlib>
14 #include <cstring>
15
16 /*
17 typedef signed long  MY_TYPE;
18 #define FORMAT RTAUDIO_SINT24
19
20 typedef char  MY_TYPE;
21 #define FORMAT RTAUDIO_SINT8
22
23 typedef signed short  MY_TYPE;
24 #define FORMAT RTAUDIO_SINT16
25
26 typedef signed long  MY_TYPE;
27 #define FORMAT RTAUDIO_SINT32
28
29 typedef float  MY_TYPE;
30 #define FORMAT RTAUDIO_FLOAT32
31 */
32
33 typedef double  MY_TYPE;
34 #define FORMAT RTAUDIO_FLOAT64
35
36 void usage( void ) {
37   // Error function in case of incorrect command-line
38   // argument specifications
39   std::cout << "\nuseage: duplex N fs <iDevice> <oDevice> <iChannelOffset> <oChannelOffset>\n";
40   std::cout << "    where N = number of channels,\n";
41   std::cout << "    fs = the sample rate,\n";
42   std::cout << "    iDevice = optional input device to use (default = 0),\n";
43   std::cout << "    oDevice = optional output device to use (default = 0),\n";
44   std::cout << "    iChannelOffset = an optional input channel offset (default = 0),\n";
45   std::cout << "    and oChannelOffset = optional output channel offset (default = 0).\n\n";
46   exit( 0 );
47 }
48
49 int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
50            double streamTime, RtAudioStreamStatus status, void *data )
51 {
52   // Since the number of input and output channels is equal, we can do
53   // a simple buffer copy operation here.
54   if ( status ) std::cout << "Stream over/underflow detected." << std::endl;
55
56   unsigned int *bytes = (unsigned int *) data;
57   memcpy( outputBuffer, inputBuffer, *bytes );
58   return 0;
59 }
60
61 int main( int argc, char *argv[] )
62 {
63   unsigned int channels, fs, bufferBytes, oDevice = 0, iDevice = 0, iOffset = 0, oOffset = 0;
64
65   // Minimal command-line checking
66   if (argc < 3 || argc > 7 ) usage();
67
68   RtAudio adac;
69   if ( adac.getDeviceCount() < 1 ) {
70     std::cout << "\nNo audio devices found!\n";
71     exit( 1 );
72   }
73
74   channels = (unsigned int) atoi(argv[1]);
75   fs = (unsigned int) atoi(argv[2]);
76   if ( argc > 3 )
77     iDevice = (unsigned int) atoi(argv[3]);
78   if ( argc > 4 )
79     oDevice = (unsigned int) atoi(argv[4]);
80   if ( argc > 5 )
81     iOffset = (unsigned int) atoi(argv[5]);
82   if ( argc > 6 )
83     oOffset = (unsigned int) atoi(argv[6]);
84
85   // Let RtAudio print messages to stderr.
86   adac.showWarnings( true );
87
88   // Set the same number of channels for both input and output.
89   unsigned int bufferFrames = 512;
90   RtAudio::StreamParameters iParams, oParams;
91   iParams.deviceId = iDevice;
92   iParams.nChannels = channels;
93   iParams.firstChannel = iOffset;
94   oParams.deviceId = oDevice;
95   oParams.nChannels = channels;
96   oParams.firstChannel = oOffset;
97
98   RtAudio::StreamOptions options;
99   //options.flags |= RTAUDIO_NONINTERLEAVED;
100
101   try {
102     adac.openStream( &oParams, &iParams, FORMAT, fs, &bufferFrames, &inout, (void *)&bufferBytes, &options );
103   }
104   catch ( RtError& e ) {
105     std::cout << '\n' << e.getMessage() << '\n' << std::endl;
106     exit( 1 );
107   }
108
109   bufferBytes = bufferFrames * channels * sizeof( MY_TYPE );
110
111   // Test RtAudio functionality for reporting latency.
112   std::cout << "\nStream latency = " << adac.getStreamLatency() << " frames" << std::endl;
113
114   try {
115     adac.startStream();
116
117     char input;
118     std::cout << "\nRunning ... press <enter> to quit (buffer frames = " << bufferFrames << ").\n";
119     std::cin.get(input);
120
121     // Stop the stream.
122     adac.stopStream();
123   }
124   catch ( RtError& e ) {
125     std::cout << '\n' << e.getMessage() << '\n' << std::endl;
126     goto cleanup;
127   }
128
129  cleanup:
130   if ( adac.isStreamOpen() ) adac.closeStream();
131
132   return 0;
133 }