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.

212 lines
4.4KB

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