Various updates to configure script, rtaudio files, and test files in preparation...
[rtaudio-cdist.git] / tests / testall.cpp
1 /******************************************/
2 /*
3   testall.cpp
4   by Gary P. Scavone, 2007-2008
5
6   This program will make a variety of calls
7   to extensively test RtAudio functionality.
8 */
9 /******************************************/
10
11 #include "RtAudio.h"
12 #include <iostream>
13
14 #define BASE_RATE 0.005
15 #define TIME   1.0
16
17 void usage( void ) {
18   // Error function in case of incorrect command-line
19   // argument specifications
20   std::cout << "\nuseage: testall N fs <iDevice> <oDevice> <iChannelOffset> <oChannelOffset>\n";
21   std::cout << "    where N = number of channels,\n";
22   std::cout << "    fs = the sample rate,\n";
23   std::cout << "    iDevice = optional input device to use (default = 0),\n";
24   std::cout << "    oDevice = optional output device to use (default = 0),\n";
25   std::cout << "    iChannelOffset = an optional input channel offset (default = 0),\n";
26   std::cout << "    and oChannelOffset = optional output channel offset (default = 0).\n\n";
27   exit( 0 );
28 }
29
30 unsigned int channels;
31
32 // Interleaved buffers
33 int sawi( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
34           double streamTime, RtAudioStreamStatus status, void *data )
35 {
36   unsigned int i, j;
37   extern unsigned int channels;
38   double *buffer = (double *) outputBuffer;
39   double *lastValues = (double *) data;
40
41   if ( status )
42     std::cout << "Stream underflow detected!" << std::endl;
43
44   for ( i=0; i<nBufferFrames; i++ ) {
45     for ( j=0; j<channels; j++ ) {
46       *buffer++ = (double) lastValues[j];
47       lastValues[j] += BASE_RATE * (j+1+(j*0.1));
48       if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
49     }
50   }
51
52   return 0;
53 }
54
55 // Non-interleaved buffers
56 int sawni( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
57            double streamTime, RtAudioStreamStatus status, void *data )
58 {
59   unsigned int i, j;
60   extern unsigned int channels;
61   double *buffer = (double *) outputBuffer;
62   double *lastValues = (double *) data;
63
64   if ( status )
65     std::cout << "Stream underflow detected!" << std::endl;
66
67   float increment;
68   for ( j=0; j<channels; j++ ) {
69     increment = BASE_RATE * (j+1+(j*0.1));
70     for ( i=0; i<nBufferFrames; i++ ) {
71       *buffer++ = (double) lastValues[j];
72       lastValues[j] += increment;
73       if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
74     }
75   }
76
77   return 0;
78 }
79
80 int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
81            double streamTime, RtAudioStreamStatus status, void *data )
82 {
83   // Since the number of input and output channels is equal, we can do
84   // a simple buffer copy operation here.
85   if ( status ) std::cout << "Stream over/underflow detected." << std::endl;
86
87   unsigned long *bytes = (unsigned long *) data;
88   memcpy( outputBuffer, inputBuffer, *bytes );
89   return 0;
90 }
91
92 int main( int argc, char *argv[] )
93 {
94   unsigned int bufferFrames, fs, oDevice = 0, iDevice = 0, iOffset = 0, oOffset = 0;
95   char input;
96
97   // minimal command-line checking
98   if (argc < 3 || argc > 7 ) usage();
99
100   RtAudio dac;
101   if ( dac.getDeviceCount() < 1 ) {
102     std::cout << "\nNo audio devices found!\n";
103     exit( 1 );
104   }
105
106   channels = (unsigned int) atoi( argv[1] );
107   fs = (unsigned int) atoi( argv[2] );
108   if ( argc > 3 )
109     iDevice = (unsigned int) atoi( argv[3] );
110   if ( argc > 4 )
111     oDevice = (unsigned int) atoi(argv[4]);
112   if ( argc > 5 )
113     iOffset = (unsigned int) atoi(argv[5]);
114   if ( argc > 6 )
115     oOffset = (unsigned int) atoi(argv[6]);
116
117   double *data = (double *) calloc( channels, sizeof( double ) );
118
119   // Let RtAudio print messages to stderr.
120   dac.showWarnings( true );
121
122   // Set our stream parameters for output only.
123   bufferFrames = 256;
124   RtAudio::StreamParameters oParams, iParams;
125   oParams.deviceId = oDevice;
126   oParams.nChannels = channels;
127   oParams.firstChannel = oOffset;
128
129   RtAudio::StreamOptions options;
130   options.flags = RTAUDIO_HOG_DEVICE;
131   try {
132     dac.openStream( &oParams, NULL, RTAUDIO_FLOAT64, fs, &bufferFrames, &sawi, (void *)data, &options );
133     std::cout << "\nStream latency = " << dac.getStreamLatency() << std::endl;
134
135     // Start the stream
136     dac.startStream();
137     std::cout << "\nPlaying ... press <enter> to stop.\n";
138     std::cin.get( input );
139
140     // Stop the stream
141     dac.stopStream();
142
143     // Restart again
144     std::cout << "Press <enter> to restart.\n";
145     std::cin.get( input );
146     dac.startStream();
147
148     // Test abort function
149     std::cout << "Playing again ... press <enter> to abort.\n";
150     std::cin.get( input );
151     dac.abortStream();
152
153     // Restart another time
154     std::cout << "Press <enter> to restart again.\n";
155     std::cin.get( input );
156     dac.startStream();
157
158     std::cout << "Playing again ... press <enter> to close the stream.\n";
159     std::cin.get( input );
160   }
161   catch ( RtError& e ) {
162     e.printMessage();
163     goto cleanup;
164   }
165
166   if ( dac.isStreamOpen() ) dac.closeStream();
167
168   // Test non-interleaved functionality
169   options.flags = RTAUDIO_NONINTERLEAVED;
170   try {
171     dac.openStream( &oParams, NULL, RTAUDIO_FLOAT64, fs, &bufferFrames, &sawni, (void *)data, &options );
172
173     std::cout << "Press <enter> to start non-interleaved playback.\n";
174     std::cin.get( input );
175
176     // Start the stream
177     dac.startStream();
178     std::cout << "\nPlaying ... press <enter> to stop.\n";
179     std::cin.get( input );
180   }
181   catch ( RtError& e ) {
182     e.printMessage();
183     goto cleanup;
184   }
185
186   if ( dac.isStreamOpen() ) dac.closeStream();
187
188   // Now open a duplex stream.
189   unsigned int bufferBytes;
190   iParams.deviceId = iDevice;
191   iParams.nChannels = channels;
192   iParams.firstChannel = iOffset;
193   options.flags = RTAUDIO_NONINTERLEAVED;
194   try {
195     dac.openStream( &oParams, &iParams, RTAUDIO_SINT32, fs, &bufferFrames, &inout, (void *)&bufferBytes, &options );
196
197     bufferBytes = bufferFrames * channels * 4;
198
199     std::cout << "Press <enter> to start duplex operation.\n";
200     std::cin.get( input );
201
202     // Start the stream
203     dac.startStream();
204     std::cout << "\nRunning ... press <enter> to stop.\n";
205     std::cin.get( input );
206
207     // Stop the stream
208     dac.stopStream();
209     std::cout << "\nStopped ... press <enter> to restart.\n";
210     std::cin.get( input );
211
212     // Restart the stream
213     dac.startStream();
214     std::cout << "\nRunning ... press <enter> to stop.\n";
215     std::cin.get( input );
216   }
217   catch ( RtError& e ) {
218     e.printMessage();
219   }
220
221  cleanup:
222   if ( dac.isStreamOpen() ) dac.closeStream();
223   free( data );
224
225   return 0;
226 }