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.

222 lines
4.7KB

  1. /******************************************/
  2. /*
  3. twostreams.cpp
  4. by Gary P. Scavone, 2001
  5. Test executable for audio playback, recording,
  6. duplex operation, stopping, starting, and
  7. aborting operations. Takes number of channels
  8. and sample rate as input arguments. Runs input
  9. and output through two separate instances of RtAudio.
  10. Uses blocking functionality.
  11. */
  12. /******************************************/
  13. #include "RtAudio.h"
  14. #include <iostream>
  15. /*
  16. typedef signed long MY_TYPE;
  17. #define FORMAT RTAUDIO_SINT24
  18. #define SCALE 2147483647.0
  19. typedef char MY_TYPE;
  20. #define FORMAT RTAUDIO_SINT8
  21. #define SCALE 127.0
  22. typedef signed short MY_TYPE;
  23. #define FORMAT RTAUDIO_SINT16
  24. #define SCALE 32767.0
  25. typedef signed long MY_TYPE;
  26. #define FORMAT RTAUDIO_SINT32
  27. #define SCALE 2147483647.0
  28. */
  29. typedef float MY_TYPE;
  30. #define FORMAT RTAUDIO_FLOAT32
  31. #define SCALE 1.0
  32. /*
  33. typedef double MY_TYPE;
  34. #define FORMAT RTAUDIO_FLOAT64
  35. #define SCALE 1.0
  36. */
  37. #define BASE_RATE 0.005
  38. #define TIME 2.0
  39. void usage(void) {
  40. /* Error function in case of incorrect command-line
  41. argument specifications
  42. */
  43. std::cout << "\nuseage: twostreams N fs <device>\n";
  44. std::cout << " where N = number of channels,\n";
  45. std::cout << " fs = the sample rate,\n";
  46. std::cout << " and device = the device to use (default = 0).\n\n";
  47. exit(0);
  48. }
  49. int main(int argc, char *argv[])
  50. {
  51. int chans, fs, buffer_size, device = 0;
  52. long frames, counter = 0, i, j;
  53. MY_TYPE *buffer1, *buffer2;
  54. RtAudio *stream1 = 0, *stream2 = 0;
  55. FILE *fd;
  56. double *data = 0;
  57. // minimal command-line checking
  58. if (argc != 3 && argc != 4 ) usage();
  59. chans = (int) atoi(argv[1]);
  60. fs = (int) atoi(argv[2]);
  61. if ( argc == 4 )
  62. device = (int) atoi(argv[3]);
  63. // Open the realtime output device
  64. buffer_size = 512;
  65. try {
  66. stream1 = new RtAudio(device, chans, 0, 0,
  67. FORMAT, fs, &buffer_size, 8);
  68. }
  69. catch (RtError &error) {
  70. error.printMessage();
  71. exit(EXIT_FAILURE);
  72. }
  73. try {
  74. stream2 = new RtAudio(0, 0, device, chans,
  75. FORMAT, fs, &buffer_size, 8);
  76. }
  77. catch (RtError &error) {
  78. delete stream1;
  79. error.printMessage();
  80. exit(EXIT_FAILURE);
  81. }
  82. try {
  83. buffer1 = (MY_TYPE *) stream1->getStreamBuffer();
  84. buffer2 = (MY_TYPE *) stream2->getStreamBuffer();
  85. }
  86. catch (RtError &error) {
  87. error.printMessage();
  88. goto cleanup;
  89. }
  90. frames = (long) (fs * TIME);
  91. data = (double *) calloc(chans, sizeof(double));
  92. try {
  93. stream1->startStream();
  94. }
  95. catch (RtError &error) {
  96. error.printMessage();
  97. goto cleanup;
  98. }
  99. std::cout << "\nStarting sawtooth playback stream for " << TIME << " seconds." << std::endl;
  100. while (counter < frames) {
  101. for (i=0; i<buffer_size; i++) {
  102. for (j=0; j<chans; j++) {
  103. buffer1[i*chans+j] = (MY_TYPE) (data[j] * SCALE);
  104. data[j] += BASE_RATE * (j+1+(j*0.1));
  105. if (data[j] >= 1.0) data[j] -= 2.0;
  106. }
  107. }
  108. try {
  109. stream1->tickStream();
  110. }
  111. catch (RtError &error) {
  112. error.printMessage();
  113. goto cleanup;
  114. }
  115. counter += buffer_size;
  116. }
  117. std::cout << "\nStopping playback stream." << std::endl;
  118. try {
  119. stream1->stopStream();
  120. }
  121. catch (RtError &error) {
  122. error.printMessage();
  123. goto cleanup;
  124. }
  125. fd = fopen("test.raw","wb");
  126. try {
  127. stream2->startStream();
  128. }
  129. catch (RtError &error) {
  130. error.printMessage();
  131. goto cleanup;
  132. }
  133. counter = 0;
  134. std::cout << "\nStarting recording stream for " << TIME << " seconds." << std::endl;
  135. while (counter < frames) {
  136. try {
  137. stream2->tickStream();
  138. }
  139. catch (RtError &error) {
  140. error.printMessage();
  141. goto cleanup;
  142. }
  143. fwrite(buffer2, sizeof(MY_TYPE), chans * buffer_size, fd);
  144. counter += buffer_size;
  145. }
  146. fclose(fd);
  147. std::cout << "\nAborting recording." << std::endl;
  148. try {
  149. stream2->abortStream();
  150. stream1->startStream();
  151. stream2->startStream();
  152. }
  153. catch (RtError &error) {
  154. error.printMessage();
  155. goto cleanup;
  156. }
  157. counter = 0;
  158. std::cout << "\nStarting playback and record streams (quasi-duplex) for " << TIME << " seconds." << std::endl;
  159. while (counter < frames) {
  160. try {
  161. stream2->tickStream();
  162. memcpy(buffer1, buffer2, sizeof(MY_TYPE) * chans * buffer_size);
  163. stream1->tickStream();
  164. }
  165. catch (RtError &error) {
  166. error.printMessage();
  167. goto cleanup;
  168. }
  169. counter += buffer_size;
  170. }
  171. std::cout << "\nStopping both streams." << std::endl;
  172. try {
  173. stream1->stopStream();
  174. stream2->stopStream();
  175. }
  176. catch (RtError &error) {
  177. error.printMessage();
  178. }
  179. cleanup:
  180. stream1->closeStream();
  181. stream2->closeStream();
  182. delete stream1;
  183. delete stream2;
  184. if (data) free(data);
  185. return 0;
  186. }