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.3KB

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