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.

178 lines
4.2KB

  1. /******************************************/
  2. /*
  3. playsaw.cpp
  4. by Gary P. Scavone, 2006
  5. This program will output sawtooth waveforms
  6. of different frequencies on each channel.
  7. */
  8. /******************************************/
  9. #include "RtAudio.h"
  10. #include <iostream>
  11. /*
  12. typedef signed long MY_TYPE;
  13. #define FORMAT RTAUDIO_SINT24
  14. #define SCALE 2147483647.0
  15. typedef char MY_TYPE;
  16. #define FORMAT RTAUDIO_SINT8
  17. #define SCALE 127.0
  18. typedef signed short MY_TYPE;
  19. #define FORMAT RTAUDIO_SINT16
  20. #define SCALE 32767.0
  21. typedef signed long MY_TYPE;
  22. #define FORMAT RTAUDIO_SINT32
  23. #define SCALE 2147483647.0
  24. */
  25. typedef float MY_TYPE;
  26. #define FORMAT RTAUDIO_FLOAT32
  27. #define SCALE 1.0
  28. /*
  29. typedef double MY_TYPE;
  30. #define FORMAT RTAUDIO_FLOAT64
  31. #define SCALE 1.0
  32. */
  33. #define BASE_RATE 0.005
  34. #define TIME 1.0
  35. void usage( void ) {
  36. // Error function in case of incorrect command-line
  37. // argument specifications
  38. std::cout << "\nuseage: playsaw N fs <device> <channelOffset>\n";
  39. std::cout << " where N = number of channels,\n";
  40. std::cout << " fs = the sample rate,\n";
  41. std::cout << " device = optional device to use (default = 0),\n";
  42. std::cout << " and channelOffset = an optional channel offset on the device (default = 0).\n\n";
  43. exit( 0 );
  44. }
  45. unsigned int channels;
  46. RtAudio::StreamOptions options;
  47. //#define USE_INTERLEAVED
  48. #if defined( USE_INTERLEAVED )
  49. // Interleaved buffers
  50. int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
  51. double streamTime, RtAudioStreamStatus status, void *data )
  52. {
  53. unsigned int i, j;
  54. extern unsigned int channels;
  55. MY_TYPE *buffer = (MY_TYPE *) outputBuffer;
  56. double *lastValues = (double *) data;
  57. if ( status )
  58. std::cout << "Stream underflow detected!" << std::endl;
  59. for ( i=0; i<nBufferFrames; i++ ) {
  60. for ( j=0; j<channels; j++ ) {
  61. *buffer++ = (MY_TYPE) (lastValues[j] * SCALE);
  62. lastValues[j] += BASE_RATE * (j+1+(j*0.1));
  63. if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
  64. }
  65. }
  66. return 0;
  67. }
  68. #else // Use non-interleaved buffers
  69. int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
  70. double streamTime, RtAudioStreamStatus status, void *data )
  71. {
  72. unsigned int i, j;
  73. extern unsigned int channels;
  74. MY_TYPE *buffer = (MY_TYPE *) outputBuffer;
  75. double *lastValues = (double *) data;
  76. if ( status )
  77. std::cout << "Stream underflow detected!" << std::endl;
  78. double increment;
  79. for ( j=0; j<channels; j++ ) {
  80. increment = BASE_RATE * (j+1+(j*0.1));
  81. for ( i=0; i<nBufferFrames; i++ ) {
  82. *buffer++ = (MY_TYPE) (lastValues[j] * SCALE);
  83. lastValues[j] += increment;
  84. if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
  85. }
  86. }
  87. return 0;
  88. }
  89. #endif
  90. int main( int argc, char *argv[] )
  91. {
  92. unsigned int bufferFrames, fs, device = 0, offset = 0;
  93. // minimal command-line checking
  94. if (argc < 3 || argc > 5 ) usage();
  95. RtAudio dac;
  96. if ( dac.getDeviceCount() < 1 ) {
  97. std::cout << "\nNo audio devices found!\n";
  98. exit( 0 );
  99. }
  100. channels = (unsigned int) atoi(argv[1]);
  101. fs = (unsigned int) atoi(argv[2]);
  102. if ( argc > 3 )
  103. device = (unsigned int) atoi(argv[3]);
  104. if ( argc > 4 )
  105. offset = (unsigned int) atoi(argv[4]);
  106. double *data;
  107. data = (double *) calloc( channels, sizeof( double ) );
  108. // Let RtAudio print messages to stderr.
  109. dac.showWarnings( true );
  110. // Set our stream parameters for output only.
  111. bufferFrames = 256;
  112. RtAudio::StreamParameters oParams;
  113. oParams.deviceId = device;
  114. oParams.nChannels = channels;
  115. oParams.firstChannel = offset;
  116. options.flags |= RTAUDIO_HOG_DEVICE;
  117. #if !defined( USE_INTERLEAVED )
  118. options.flags |= RTAUDIO_NONINTERLEAVED;
  119. #endif
  120. try {
  121. dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &saw, (void *)data, &options );
  122. dac.startStream();
  123. }
  124. catch ( RtError& e ) {
  125. e.printMessage();
  126. goto cleanup;
  127. }
  128. char input;
  129. std::cout << "\nPlaying ... press <enter> to quit (buffer size = " << bufferFrames << ").\n";
  130. std::cin.get( input );
  131. try {
  132. // Stop the stream
  133. std::cout << "Stream latency = " << dac.getStreamLatency() << "\n" << std::endl;
  134. dac.stopStream();
  135. }
  136. catch ( RtError& e ) {
  137. e.printMessage();
  138. }
  139. cleanup:
  140. if ( dac.isStreamOpen() ) dac.closeStream();
  141. free( data );
  142. return 0;
  143. }