Audio plugin host https://kx.studio/carla
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.

playsaw.cpp 5.3KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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 char MY_TYPE;
  14. #define FORMAT RTAUDIO_SINT8
  15. #define SCALE 127.0
  16. */
  17. typedef signed short MY_TYPE;
  18. #define FORMAT RTAUDIO_SINT16
  19. #define SCALE 32767.0
  20. /*
  21. typedef S24 MY_TYPE;
  22. #define FORMAT RTAUDIO_SINT24
  23. #define SCALE 8388607.0
  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. // Platform-dependent sleep routines.
  35. #if defined( __WINDOWS_ASIO__ ) || defined( __WINDOWS_DS__ )
  36. #include <windows.h>
  37. #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds )
  38. #else // Unix variants
  39. #include <unistd.h>
  40. #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )
  41. #endif
  42. #define BASE_RATE 0.005
  43. #define TIME 1.0
  44. void usage( void ) {
  45. // Error function in case of incorrect command-line
  46. // argument specifications
  47. std::cout << "\nuseage: playsaw N fs <device> <channelOffset> <time>\n";
  48. std::cout << " where N = number of channels,\n";
  49. std::cout << " fs = the sample rate,\n";
  50. std::cout << " device = optional device to use (default = 0),\n";
  51. std::cout << " channelOffset = an optional channel offset on the device (default = 0),\n";
  52. std::cout << " and time = an optional time duration in seconds (default = no limit).\n\n";
  53. exit( 0 );
  54. }
  55. unsigned int channels;
  56. RtAudio::StreamOptions options;
  57. unsigned int frameCounter = 0;
  58. bool checkCount = false;
  59. unsigned int nFrames = 0;
  60. const unsigned int callbackReturnValue = 1;
  61. //#define USE_INTERLEAVED
  62. #if defined( USE_INTERLEAVED )
  63. // Interleaved buffers
  64. int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
  65. double streamTime, RtAudioStreamStatus status, void *data )
  66. {
  67. unsigned int i, j;
  68. extern unsigned int channels;
  69. MY_TYPE *buffer = (MY_TYPE *) outputBuffer;
  70. double *lastValues = (double *) data;
  71. if ( status )
  72. std::cout << "Stream underflow detected!" << std::endl;
  73. for ( i=0; i<nBufferFrames; i++ ) {
  74. for ( j=0; j<channels; j++ ) {
  75. *buffer++ = (MY_TYPE) (lastValues[j] * SCALE * 0.5);
  76. lastValues[j] += BASE_RATE * (j+1+(j*0.1));
  77. if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
  78. }
  79. }
  80. frameCounter += nBufferFrames;
  81. if ( checkCount && ( frameCounter >= nFrames ) ) return callbackReturnValue;
  82. return 0;
  83. }
  84. #else // Use non-interleaved buffers
  85. int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
  86. double streamTime, RtAudioStreamStatus status, void *data )
  87. {
  88. unsigned int i, j;
  89. extern unsigned int channels;
  90. MY_TYPE *buffer = (MY_TYPE *) outputBuffer;
  91. double *lastValues = (double *) data;
  92. if ( status )
  93. std::cout << "Stream underflow detected!" << std::endl;
  94. double increment;
  95. for ( j=0; j<channels; j++ ) {
  96. increment = BASE_RATE * (j+1+(j*0.1));
  97. for ( i=0; i<nBufferFrames; i++ ) {
  98. *buffer++ = (MY_TYPE) (lastValues[j] * SCALE * 0.5);
  99. lastValues[j] += increment;
  100. if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
  101. }
  102. }
  103. frameCounter += nBufferFrames;
  104. if ( checkCount && ( frameCounter >= nFrames ) ) return callbackReturnValue;
  105. return 0;
  106. }
  107. #endif
  108. int main( int argc, char *argv[] )
  109. {
  110. unsigned int bufferFrames, fs, device = 0, offset = 0;
  111. // minimal command-line checking
  112. if (argc < 3 || argc > 6 ) usage();
  113. RtAudio dac;
  114. if ( dac.getDeviceCount() < 1 ) {
  115. std::cout << "\nNo audio devices found!\n";
  116. exit( 1 );
  117. }
  118. channels = (unsigned int) atoi( argv[1] );
  119. fs = (unsigned int) atoi( argv[2] );
  120. if ( argc > 3 )
  121. device = (unsigned int) atoi( argv[3] );
  122. if ( argc > 4 )
  123. offset = (unsigned int) atoi( argv[4] );
  124. if ( argc > 5 )
  125. nFrames = (unsigned int) (fs * atof( argv[5] ));
  126. if ( nFrames > 0 ) checkCount = true;
  127. double *data = (double *) calloc( channels, sizeof( double ) );
  128. // Let RtAudio print messages to stderr.
  129. dac.showWarnings( true );
  130. // Set our stream parameters for output only.
  131. bufferFrames = 512;
  132. RtAudio::StreamParameters oParams;
  133. oParams.deviceId = device;
  134. oParams.nChannels = channels;
  135. oParams.firstChannel = offset;
  136. options.flags = RTAUDIO_HOG_DEVICE;
  137. options.flags |= RTAUDIO_SCHEDULE_REALTIME;
  138. #if !defined( USE_INTERLEAVED )
  139. options.flags |= RTAUDIO_NONINTERLEAVED;
  140. #endif
  141. try {
  142. dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &saw, (void *)data, &options );
  143. dac.startStream();
  144. }
  145. catch ( RtError& e ) {
  146. e.printMessage();
  147. goto cleanup;
  148. }
  149. if ( checkCount ) {
  150. while ( dac.isStreamRunning() == true ) SLEEP( 100 );
  151. }
  152. else {
  153. char input;
  154. //std::cout << "Stream latency = " << dac.getStreamLatency() << "\n" << std::endl;
  155. std::cout << "\nPlaying ... press <enter> to quit (buffer size = " << bufferFrames << ").\n";
  156. std::cin.get( input );
  157. try {
  158. // Stop the stream
  159. dac.stopStream();
  160. }
  161. catch ( RtError& e ) {
  162. e.printMessage();
  163. }
  164. }
  165. cleanup:
  166. if ( dac.isStreamOpen() ) dac.closeStream();
  167. free( data );
  168. return 0;
  169. }