6159b88b00fb065c259cc58d948cb77b721d0a9f
[rtaudio-cdist.git] / tests / teststops.cpp
1 /******************************************/\r
2 /*\r
3   teststop.cpp\r
4   by Gary P. Scavone, 2011\r
5 \r
6   This program starts and stops an RtAudio\r
7   stream many times in succession and in\r
8   different ways to to test its functionality.\r
9 */\r
10 /******************************************/\r
11 \r
12 #include "RtAudio.h"\r
13 #include <iostream>\r
14 #include <cstdlib>\r
15 #include <cstring>\r
16 #include <cstdio>\r
17 \r
18 #define PULSE_RATE 0.01  // seconds\r
19 #define RUNTIME    0.4   // seconds\r
20 #define PAUSETIME  0.1   // seconds\r
21 #define REPETITIONS 10\r
22 \r
23 // Platform-dependent sleep routines.\r
24 #if defined( __WINDOWS_ASIO__ ) || defined( __WINDOWS_DS__ ) || defined( __WINDOWS_WASAPI__ )\r
25   #include <windows.h>\r
26   #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) \r
27 #else // Unix variants\r
28   #include <unistd.h>\r
29   #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )\r
30 #endif\r
31 \r
32 void usage( void ) {\r
33   // Error function in case of incorrect command-line\r
34   // argument specifications\r
35   std::cout << "\nuseage: teststops N fs <iDevice> <oDevice> <iChannelOffset> <oChannelOffset>\n";\r
36   std::cout << "    where N = number of channels,\n";\r
37   std::cout << "    fs = the sample rate,\n";\r
38   std::cout << "    iDevice = optional input device to use (default = 0),\n";\r
39   std::cout << "    oDevice = optional output device to use (default = 0),\n";\r
40   std::cout << "    iChannelOffset = an optional input channel offset (default = 0),\n";\r
41   std::cout << "    and oChannelOffset = optional output channel offset (default = 0).\n\n";\r
42   exit( 0 );\r
43 }\r
44 \r
45 struct MyData {\r
46   unsigned int channels;\r
47   unsigned int pulseCount;\r
48   unsigned int frameCounter;\r
49   unsigned int nFrames;\r
50   unsigned int returnValue;\r
51 };\r
52 \r
53 // Interleaved buffers\r
54 int pulse( void *outputBuffer, void * /*inputBuffer*/, unsigned int nBufferFrames,\r
55            double /*streamTime*/, RtAudioStreamStatus status, void *mydata )\r
56 {\r
57   // Write out a pulse signal and ignore the input buffer.\r
58   unsigned int i, j;\r
59   float sample;\r
60   float *buffer = (float *) outputBuffer;\r
61   MyData *data = (MyData *) mydata;\r
62 \r
63   if ( status ) std::cout << "Stream over/underflow detected!" << std::endl;\r
64 \r
65   for ( i=0; i<nBufferFrames; i++ ) {\r
66     if ( data->frameCounter % data->pulseCount == 0 ) sample = 0.9f;\r
67     else sample = 0.0;\r
68     for ( j=0; j<data->channels; j++ )\r
69       *buffer++ = sample;\r
70 \r
71     data->frameCounter++;\r
72   }\r
73 \r
74   if ( data->frameCounter >= data->nFrames )\r
75     return data->returnValue;\r
76   else\r
77     return 0;\r
78 }\r
79 \r
80 int main( int argc, char *argv[] )\r
81 {\r
82   unsigned int bufferFrames, fs, oDevice = 0, iDevice = 0, iOffset = 0, oOffset = 0;\r
83   unsigned int runtime, pausetime;\r
84   char input;\r
85 \r
86   // minimal command-line checking\r
87   if (argc < 3 || argc > 7 ) usage();\r
88 \r
89   RtAudio *adc = new RtAudio();\r
90   if ( adc->getDeviceCount() < 1 ) {\r
91     std::cout << "\nNo audio devices found!\n";\r
92     exit( 1 );\r
93   }\r
94 \r
95   MyData mydata;\r
96   mydata.channels = (unsigned int) atoi( argv[1] );\r
97   fs = (unsigned int) atoi( argv[2] );\r
98   if ( argc > 3 )\r
99     iDevice = (unsigned int) atoi( argv[3] );\r
100   if ( argc > 4 )\r
101     oDevice = (unsigned int) atoi(argv[4]);\r
102   if ( argc > 5 )\r
103     iOffset = (unsigned int) atoi(argv[5]);\r
104   if ( argc > 6 )\r
105     oOffset = (unsigned int) atoi(argv[6]);\r
106 \r
107   // Let RtAudio print messages to stderr.\r
108   adc->showWarnings( true );\r
109 \r
110   runtime = static_cast<unsigned int>(RUNTIME * 1000);\r
111   pausetime = static_cast<unsigned int>(PAUSETIME * 1000);\r
112 \r
113   // Set our stream parameters for a duplex stream.\r
114   bufferFrames = 512;\r
115   RtAudio::StreamParameters oParams, iParams;\r
116   oParams.deviceId = oDevice;\r
117   oParams.nChannels = mydata.channels;\r
118   oParams.firstChannel = oOffset;\r
119 \r
120   iParams.deviceId = iDevice;\r
121   iParams.nChannels = mydata.channels;\r
122   iParams.firstChannel = iOffset;\r
123 \r
124   if ( iDevice == 0 )\r
125     iParams.deviceId = adc->getDefaultInputDevice();\r
126   if ( oDevice == 0 )\r
127     oParams.deviceId = adc->getDefaultOutputDevice();\r
128 \r
129   // First, test external stopStream() calls.\r
130   mydata.pulseCount = static_cast<unsigned int>(PULSE_RATE * fs);\r
131   mydata.nFrames = 50 * fs;\r
132   mydata.returnValue = 0;\r
133   try {\r
134     adc->openStream( &oParams, &iParams, RTAUDIO_SINT32, fs, &bufferFrames, &pulse, (void *)&mydata );\r
135 \r
136     std::cout << "Press <enter> to start test.\n";\r
137     std::cin.get( input );\r
138 \r
139     for (int i=0; i<REPETITIONS; i++ ) {\r
140       mydata.frameCounter = 0;\r
141       adc->startStream();\r
142       std::cout << "Stream started ... ";\r
143       SLEEP( runtime );\r
144       adc->stopStream();\r
145       std::cout << "stream externally stopped.\n";\r
146       SLEEP( pausetime );\r
147     }\r
148   }\r
149   catch ( RtAudioError& e ) {\r
150     e.printMessage();\r
151     goto cleanup;\r
152   }\r
153 \r
154   adc->closeStream();\r
155 \r
156   // Next, test internal stopStream() calls.\r
157   mydata.nFrames = (unsigned int) (RUNTIME * fs);\r
158   mydata.returnValue = 1;\r
159   try {\r
160     adc->openStream( &oParams, &iParams, RTAUDIO_SINT32, fs, &bufferFrames, &pulse, (void *)&mydata );\r
161 \r
162     std::cin.clear();\r
163     fflush(stdin);\r
164     std::cout << "\nPress <enter> to continue test.\n";\r
165     std::cin.get( input );\r
166 \r
167     for (int i=0; i<REPETITIONS; i++ ) {\r
168       mydata.frameCounter = 0;\r
169       adc->startStream();\r
170       std::cout << "Stream started ... ";\r
171       while ( adc->isStreamRunning() ) SLEEP( 5 );\r
172       std::cout << "stream stopped via callback return value = 1.\n";\r
173       SLEEP( pausetime );\r
174     }\r
175   }\r
176   catch ( RtAudioError& e ) {\r
177     e.printMessage();\r
178     goto cleanup;\r
179   }\r
180 \r
181   adc->closeStream();\r
182 \r
183   // Test internal abortStream() calls.\r
184   mydata.returnValue = 2;\r
185   try {\r
186     adc->openStream( &oParams, &iParams, RTAUDIO_SINT32, fs, &bufferFrames, &pulse, (void *)&mydata );\r
187     std::cin.clear();\r
188     fflush(stdin);\r
189     std::cout << "\nPress <enter> to continue test.\n";\r
190     std::cin.get( input );\r
191 \r
192     for (int i=0; i<REPETITIONS; i++ ) {\r
193       mydata.frameCounter = 0;\r
194       adc->startStream();\r
195       std::cout << "Stream started ... ";\r
196       while ( adc->isStreamRunning() ) SLEEP( 5 );\r
197       std::cout << "stream aborted via callback return value = 2.\n";\r
198       SLEEP( pausetime );\r
199     }\r
200   }\r
201   catch ( RtAudioError& e ) {\r
202     e.printMessage();\r
203     goto cleanup;\r
204   }\r
205 \r
206   adc->closeStream();\r
207 \r
208   // Test consecutive stream re-opening.\r
209   mydata.returnValue = 0;\r
210   mydata.nFrames = 50 * fs;\r
211   try {\r
212 \r
213     std::cin.clear();\r
214     fflush(stdin);\r
215     std::cout << "\nPress <enter> to continue test.\n";\r
216     std::cin.get( input );\r
217 \r
218     for (int i=0; i<REPETITIONS; i++ ) {\r
219       adc->openStream( &oParams, &iParams, RTAUDIO_SINT32, fs, &bufferFrames, &pulse, (void *)&mydata );\r
220       mydata.frameCounter = 0;\r
221       adc->startStream();\r
222       std::cout << "New stream started ... ";\r
223       SLEEP( runtime );\r
224       adc->stopStream();\r
225       adc->closeStream();\r
226       std::cout << "stream stopped externally and closed.\n";\r
227       SLEEP( pausetime );\r
228     }\r
229   }\r
230   catch ( RtAudioError& e ) {\r
231     e.printMessage();\r
232     goto cleanup;\r
233   }\r
234 \r
235   delete adc;\r
236   adc = 0;\r
237 \r
238   // Test consecutive RtAudio creating and deletion.\r
239   try {\r
240 \r
241     std::cin.clear();\r
242     fflush(stdin);\r
243     std::cout << "\nPress <enter> to continue test.\n";\r
244     std::cin.get( input );\r
245 \r
246     for (int i=0; i<REPETITIONS; i++ ) {\r
247       adc = new RtAudio();      \r
248       adc->openStream( &oParams, &iParams, RTAUDIO_SINT32, fs, &bufferFrames, &pulse, (void *)&mydata );\r
249       mydata.frameCounter = 0;\r
250       adc->startStream();\r
251       std::cout << "New instance and stream started ... ";\r
252       SLEEP( runtime );\r
253       adc->stopStream();\r
254       adc->closeStream();\r
255       delete adc;\r
256       adc = 0;\r
257       std::cout << "stream stopped and instance deleted.\n";\r
258       SLEEP( pausetime );\r
259     }\r
260   }\r
261   catch ( RtAudioError& e ) {\r
262     e.printMessage();\r
263     goto cleanup;\r
264   }\r
265 \r
266  cleanup:\r
267   if ( adc && adc->isStreamOpen() ) adc->closeStream();\r
268   if ( adc ) delete adc;\r
269 \r
270   return 0;\r
271 }\r