Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.4KB

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