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.

140 lines
3.6KB

  1. /******************************************/
  2. /*
  3. Example program to play an N channel
  4. soundfile.
  5. This program will load WAV, SND, AIF, and
  6. MAT-file formatted files of various data
  7. types. If the audio system does not support
  8. the number of channels or sample rate of
  9. the soundfile, the program will stop.
  10. By Gary P. Scavone, 2000 - 2004.
  11. */
  12. /******************************************/
  13. #include "FileWvIn.h"
  14. #include "RtAudio.h"
  15. #include <signal.h>
  16. #include <iostream>
  17. #include <cstdlib>
  18. using namespace stk;
  19. // Eewww ... global variables! :-)
  20. bool done = false;
  21. StkFrames frames;
  22. static void finish(int ignore){ done = true; }
  23. void usage(void) {
  24. // Error function in case of incorrect command-line
  25. // argument specifications.
  26. std::cout << "\nuseage: play file sr <rate>\n";
  27. std::cout << " where file = the file to play,\n";
  28. std::cout << " where sr = sample rate,\n";
  29. std::cout << " and rate = an optional playback rate.\n";
  30. std::cout << " (default = 1.0, can be negative)\n\n";
  31. exit( 0 );
  32. }
  33. // This tick() function handles sample computation only. It will be
  34. // called automatically when the system needs a new buffer of audio
  35. // samples.
  36. int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
  37. double streamTime, RtAudioStreamStatus status, void *userData )
  38. {
  39. FileWvIn *input = (FileWvIn *) userData;
  40. StkFloat *samples = (StkFloat *) outputBuffer;
  41. input->tick( frames );
  42. for ( unsigned int i=0; i<frames.size(); i++ ) {
  43. *samples++ = frames[i];
  44. if ( input->channelsOut() == 1 ) *samples++ = frames[i]; // play mono files in stereo
  45. }
  46. if ( input->isFinished() ) {
  47. done = true;
  48. return 1;
  49. }
  50. else
  51. return 0;
  52. }
  53. int main(int argc, char *argv[])
  54. {
  55. // Minimal command-line checking.
  56. if ( argc < 3 || argc > 4 ) usage();
  57. // Set the global sample rate before creating class instances.
  58. Stk::setSampleRate( (StkFloat) atof( argv[2] ) );
  59. // Initialize our WvIn and RtAudio pointers.
  60. RtAudio dac;
  61. FileWvIn input;
  62. // Try to load the soundfile.
  63. try {
  64. input.openFile( argv[1] );
  65. }
  66. catch ( StkError & ) {
  67. exit( 1 );
  68. }
  69. // Set input read rate based on the default STK sample rate.
  70. double rate = 1.0;
  71. rate = input.getFileRate() / Stk::sampleRate();
  72. if ( argc == 4 ) rate *= atof( argv[3] );
  73. input.setRate( rate );
  74. input.ignoreSampleRateChange();
  75. // Find out how many channels we have.
  76. int channels = input.channelsOut();
  77. // Figure out how many bytes in an StkFloat and setup the RtAudio stream.
  78. RtAudio::StreamParameters parameters;
  79. parameters.deviceId = dac.getDefaultOutputDevice();
  80. parameters.nChannels = ( channels == 1 ) ? 2 : channels; // Play mono files as stereo.
  81. RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
  82. unsigned int bufferFrames = RT_BUFFER_SIZE;
  83. try {
  84. dac.openStream( &parameters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&input );
  85. }
  86. catch ( RtAudioError &error ) {
  87. error.printMessage();
  88. goto cleanup;
  89. }
  90. // Install an interrupt handler function.
  91. (void) signal(SIGINT, finish);
  92. // Resize the StkFrames object appropriately.
  93. frames.resize( bufferFrames, channels );
  94. try {
  95. dac.startStream();
  96. }
  97. catch ( RtAudioError &error ) {
  98. error.printMessage();
  99. goto cleanup;
  100. }
  101. // Block waiting until callback signals done.
  102. while ( !done )
  103. Stk::sleep( 100 );
  104. // By returning a non-zero value in the callback above, the stream
  105. // is automatically stopped. But we should still close it.
  106. try {
  107. dac.closeStream();
  108. }
  109. catch ( RtAudioError &error ) {
  110. error.printMessage();
  111. }
  112. cleanup:
  113. return 0;
  114. }