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