/*
 *  Program: SDK_EX2.C
 *   Author: Philip VanBaren
 *  Purpose: This program demonstrates how to use the Media Vision SDK routines
 *           to do simple continuous data output.
 */

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>

#include <pcmio.h>

extern int DMARunning;     /* SDK flag that indicates when DMA has been started */

#define IRQ -1             /* -1 means use the default value */
#define DMA -1             /* -1 means use the default value */
#define DMASize 16         /* 16k DMA buffer */
#define DMADivisions 4     /* 4 divisions in this buffer */

#define SamplingRate 22050
#define StereoFlag 0       /* When this is 1, the data is interleaved left/right */
#define CompressionFlag 0
#define SampleSize 16      /* Number of bits per sample, 8 or 16 */

#define BUFFERS 2
#define BUF_LEN 10000
int out_buf[BUFFERS][BUF_LEN];
int buf_ready[BUFFERS];
int current_buffer=0;

/*
 *  This function is called when the PAS code is finished with a buffer.
 */
void far callback(void)
{
   buf_ready[current_buffer]=1;
   if(++current_buffer>=BUFFERS)
      current_buffer=0;
}

void main(void)
{
   int play_buffer=0;
   int i;
   for(i=0;i<BUFFERS;i++)
      buf_ready[i]=1;

   /*
    *  Initialize ProAudio stuff
    */
   if(OpenPCMBuffering(DMA,IRQ,DMASize,DMADivisions)!=0)
      puts("Error trying to open PCM buffering.");
   else if(PCMState(SamplingRate,StereoFlag,CompressionFlag,SampleSize)!=0)
      puts("Error setting sample rate.");
   else
   {
      while(!kbhit())
      {
         /*
          *  Wait for the buffer to become ready
          */
         while(!buf_ready[play_buffer]);

         /* 
          *  Insert your code here to put meaningful data in out_buf[play_buffer]
          */
         for(i=0;i<BUF_LEN;i++)
             out_buf[play_buffer][i]=floor(20000*sin(2*M_PI*0.1*i));

         /*
          *  Flag buffer as full.  This flag will become true after the buffer
          *  has been played.
          */
         buf_ready[play_buffer]=0;

         /*
          *  If DMA is not running, we need to restart it, else we can just queue
          *  up another block and it will play when the current ones are done.
          */
         if(!DMARunning)
         {
            if(PlayThisBlock((char *)out_buf[play_buffer],(long)BUF_LEN*2,callback)!=0)
            {
               ClosePCMBuffering();
               puts("Error playing block.");
               exit(1);
            }
         }
         else
         {
            if(QueueThisBlock((char *)out_buf[play_buffer],(long)BUF_LEN*2,callback)!=0)
            {
               ClosePCMBuffering();
               puts("Error playing block.");
               exit(1);
            }
         }
         if(++play_buffer>=BUFFERS)
            play_buffer=0;
      }
   }
   /*
    *  You MUST call this function before ending the program, else things won't
    *  work right the next time you try to run the program.  This is critical to
    *  remember when debugging the program, because in debugging you often quit the
    *  program before it runs to completion.  The only way I know of to recover
    *  if this function is NOT called is to reboot the computer!
    */
   ClosePCMBuffering();
}

