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.

196 lines
4.2KB

  1. /******************************************/
  2. /*
  3. twostreams.cpp
  4. by Gary P. Scavone, 2001
  5. Text 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. typedef float MY_TYPE;
  31. #define FORMAT RtAudio::RTAUDIO_FLOAT32
  32. #define SCALE 1.0
  33. */
  34. typedef double MY_TYPE;
  35. #define FORMAT RtAudio::RTAUDIO_FLOAT64
  36. #define SCALE 1.0
  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. cout << "\nuseage: twostreams N fs\n";
  44. cout << " where N = number of channels,\n";
  45. cout << " and fs = the sample rate.\n\n";
  46. exit(0);
  47. }
  48. int main(int argc, char *argv[])
  49. {
  50. int chans, fs, device, buffer_size, stream1, stream2;
  51. long frames, counter = 0, i, j;
  52. MY_TYPE *buffer1, *buffer2;
  53. RtAudio *audio;
  54. FILE *fd;
  55. double *data;
  56. // minimal command-line checking
  57. if (argc != 3) usage();
  58. chans = (int) atoi(argv[1]);
  59. fs = (int) atoi(argv[2]);
  60. // Open the realtime output device
  61. buffer_size = 512;
  62. device = 0; // default device
  63. try {
  64. audio = new RtAudio();
  65. }
  66. catch (RtError &) {
  67. exit(EXIT_FAILURE);
  68. }
  69. try {
  70. stream1 = audio->openStream(device, chans, 0, 0,
  71. FORMAT, fs, &buffer_size, 8);
  72. stream2 = audio->openStream(0, 0, device, chans,
  73. FORMAT, fs, &buffer_size, 8);
  74. buffer1 = (MY_TYPE *) audio->getStreamBuffer(stream1);
  75. buffer2 = (MY_TYPE *) audio->getStreamBuffer(stream2);
  76. }
  77. catch (RtError &) {
  78. goto cleanup;
  79. }
  80. frames = (long) (fs * TIME);
  81. data = (double *) calloc(chans, sizeof(double));
  82. try {
  83. audio->startStream(stream1);
  84. }
  85. catch (RtError &) {
  86. goto cleanup;
  87. }
  88. cout << "\nStarting sawtooth playback stream for " << TIME << " seconds." << endl;
  89. while (counter < frames) {
  90. for (i=0; i<buffer_size; i++) {
  91. for (j=0; j<chans; j++) {
  92. buffer1[i*chans+j] = (MY_TYPE) (data[j] * SCALE);
  93. data[j] += BASE_RATE * (j+1+(j*0.1));
  94. if (data[j] >= 1.0) data[j] -= 2.0;
  95. }
  96. }
  97. try {
  98. audio->tickStream(stream1);
  99. }
  100. catch (RtError &) {
  101. goto cleanup;
  102. }
  103. counter += buffer_size;
  104. }
  105. cout << "\nStopping playback stream." << endl;
  106. try {
  107. audio->stopStream(stream1);
  108. audio->startStream(stream2);
  109. }
  110. catch (RtError &) {
  111. goto cleanup;
  112. }
  113. fd = fopen("test.raw","wb");
  114. counter = 0;
  115. cout << "\nStarting recording stream for " << TIME << " seconds." << endl;
  116. while (counter < frames) {
  117. try {
  118. audio->tickStream(stream2);
  119. }
  120. catch (RtError &) {
  121. goto cleanup;
  122. }
  123. fwrite(buffer2, sizeof(MY_TYPE), chans * buffer_size, fd);
  124. counter += buffer_size;
  125. }
  126. fclose(fd);
  127. cout << "\nAborting recording." << endl;
  128. try {
  129. audio->abortStream(stream2);
  130. audio->startStream(stream1);
  131. audio->startStream(stream2);
  132. }
  133. catch (RtError &) {
  134. goto cleanup;
  135. }
  136. counter = 0;
  137. cout << "\nStarting playback and record streams (quasi-duplex) for " << TIME << " seconds." << endl;
  138. while (counter < frames) {
  139. try {
  140. audio->tickStream(stream2);
  141. memcpy(buffer1, buffer2, sizeof(MY_TYPE) * chans * buffer_size);
  142. audio->tickStream(stream1);
  143. }
  144. catch (RtError &) {
  145. goto cleanup;
  146. }
  147. counter += buffer_size;
  148. }
  149. cout << "\nStopping both streams." << endl;
  150. try {
  151. audio->stopStream(stream1);
  152. audio->stopStream(stream2);
  153. }
  154. catch (RtError &) {
  155. }
  156. cleanup:
  157. audio->closeStream(stream1);
  158. audio->closeStream(stream2);
  159. delete audio;
  160. if (data) free(data);
  161. return 0;
  162. }