#include <cmath>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include "RtAudio.h"

int myCallback(void *outputBuffer, void *inputBuffer, unsigned int bufferFrames, double streamTime, RtAudioStreamStatus status, void *userData) {
  unsigned int i, j;
  float *buffer = (float *) outputBuffer;

  if ( status )
    std::cout << "Stream underflow detected!" << std::endl;

  if (!buffer)
    return 0;

  // Write interleaved audio data.
  static int t = 0;
  for ( i=0; i<bufferFrames/2; i++ ) {
    for ( j=0; j<2; j++ ) {
      *buffer++ = 0; // 0.25*cosf((t/(float)1000)); 

    }
    if (++t > 1000) t = 0;
  }
    
  return 0;
}

int main() {
  RtAudio audio;

  // Determine the number of devices available
  unsigned int devices = audio.getDeviceCount();
  std::cout << devices << " devices found\n";

  // Scan through devices for various capabilities
  RtAudio::DeviceInfo info;
  for ( unsigned int i=0; i<devices; i++ ) {

    info = audio.getDeviceInfo( i );

    if ( info.probed == true ) {
      // Print, for example, the maximum number of output channels for each device
      std::cout << "device: #" << i << " - " << info.name << "\n";
      std::cout << "  output channels: " << info.outputChannels << "\n";
      std::cout << "  input channels: " << info.inputChannels << "\n";
      std::cout << "  duplex channels: " << info.duplexChannels << "\n";
      std::cout << "  default input/output: " << info.isDefaultInput << " / " << info.isDefaultOutput << "\n";
      
      std::cout << "  sample rates:\n";
      for (std::vector<unsigned int>::iterator i = info.sampleRates.begin(); i != info.sampleRates.end(); i++) {
          std::cout << "    " << *i << "\n";
      }
      std::cout << "  data formats:\n";      
      if (info.nativeFormats & RTAUDIO_SINT8) std::cout << "    signed 8-bit\n";
      if (info.nativeFormats & RTAUDIO_SINT16) std::cout << "    signed 16-bit\n";
      if (info.nativeFormats & RTAUDIO_SINT24) std::cout << "    signed 24-bit\n";
      if (info.nativeFormats & RTAUDIO_SINT32) std::cout << "    signed 32-bit\n";
      if (info.nativeFormats & RTAUDIO_FLOAT32) std::cout << "    32-bit float [-1,1]\n";
      if (info.nativeFormats & RTAUDIO_FLOAT64) std::cout << "    64-bit float [-1,1]\n";
    }
    else
      std::cout << "device: #" << i << " - not probed\n";
  }

  RtAudio::StreamParameters oparam;
  oparam.deviceId = audio.getDefaultOutputDevice();
  oparam.nChannels = 1;
  oparam.firstChannel = 0;

  RtAudio::StreamParameters iparam;
  iparam.deviceId = audio.getDefaultInputDevice();
  iparam.nChannels = 1;
  iparam.firstChannel = 0;

    
  unsigned int sampleRate = 44100;
  unsigned int bufferFrames = 256; // 256 sample frames

  RtAudio::StreamOptions options;
  options.flags = 0;
  options.numberOfBuffers = 2;
  options.streamName = "test";

    
  try {
    audio.openStream( &oparam, &iparam, RTAUDIO_FLOAT32,
                    sampleRate, &bufferFrames, &myCallback, (void*) 0, &options );
    audio.startStream();
  }
  catch ( RtError& e ) {
    std::cout << '\n' << e.getMessage() << '\n' << std::endl;
    exit( EXIT_FAILURE );
  }

  char input;
  std::cout << "\nPlaying ... press <enter> to quit.\n";
  std::cin.get( input );

  try {
    // Stop the stream
    audio.stopStream();
  }
  catch (RtError& e) {
    e.printMessage();
  }

  if ( audio.isStreamOpen() ) 
    audio.closeStream();

  return EXIT_SUCCESS;
}
