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.

177 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. #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. #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 << "Stream latency = " << dac.getStreamLatency() << "\n" << std::endl;
  130. std::cout << "\nPlaying ... press <enter> to quit (buffer size = " << bufferFrames << ").\n";
  131. std::cin.get( input );
  132. try {
  133. // Stop the stream
  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. }