/*
Rod Jard Paholio
50849727
1-19-2005

For this assignment I attempted to make the sound fade in and
fade out.  I decided to use Prof. Dobrian's pa_cosine.c code as
a template and modified it to my specifications to achieve what I wanted.
I just experimented with the code and got very interesting results.

I thought about what I needed to modify and changed the:

-NUM_SECONDS to 25 seconds so I could heear the whole cosine swing
-FREQUENCY to 2000 Hz
-Changed the magnitude by multiplying leeft channel by 1000 and adding 1
 and the right channel by multiplying that just by 1000.
-This change at different times creates  a high pitch sound that lowers as if a bomb 
 was being dropped and then it levels off.  All this occurs within 30 seconds. 
 It will have an effect of fading in and out or as if a bomb was being dropped.
-I also added a Sine Wave to the Cosine  wave, which made the sound even more interesting.
 It sounds like an up and down kind of sound where it goes from high frequency to low.
-More than 2 million samples taken, has  a very interesting sound effect!
-On another note, this "noise" made me nnauseous
*/

/*
 * pa_cosine.c
 * Generate a cosine wave
 *
 * Author: Christopher Dobrian
 *
 * This program uses the PortAudio Portable Audio Library.
 * For more information see: http://www.portaudio.com
 *
 */

#include 
#include 

//#include "pa_common\pa_lib.c"
#include "pa_common\portaudio.h"
#include "pa_common\pa_host.h"
#include "pa_win_wmme\pa_win_wmme.c"

#define NUM_SECONDS   (25) //modified: 25 seconds instead of 4 seconds
#define SAMPLE_RATE   (44100) //same
#define BUFFER_SIZE   (256) //same
#define TWOPI         (6.283185307179586)
#define FREQUENCY     2000. //modified: 2 KHz instead of 1 KHz

typedef struct {
    float amplitude;
    float frequency;
    float phase;
    unsigned long count;
} paAudioData;

/* This routine will be called by the PortAudio engine when audio is needed. */

static int cosineCallback( void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData );

static int cosineCallback( void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData )
{

    /* Cast data passed through stream to the format of the local structure. */
    paAudioData *data = (paAudioData*)userData;
    // float *in = (float*)inputBuffer; // input buffer only needed for input
    float *out = (float*)outputBuffer;
	
    unsigned int i; // just a counter

    float A = data->amplitude;
    float twopiFoverR = TWOPI*data->frequency/SAMPLE_RATE;
    float phase = data->phase;
    float y; // temp variable for output sample

    data->amplitude = data->amplitude *.999; /*Prof. Dobrian's method to adjust the amp.*/
    data->frequency = data->frequency *.999;
	
    for( i = 0 ; i < framesPerBuffer ; i++ )
    {
        y = A*cos(twopiFoverR*(data->count++)+phase) + A*sin(twopiFoverR*(data->count++)+phase); /*added a Sine Wave on top of the Cosine Wave*/
        *out++ = 1000*y + 1;	/* left channel */ /*decided to modify this part by changing the magnitude.*/
        *out++ = 1000*y;	/* right channel*/
    }

    return 0;
}

/*******************************************************************/

static paAudioData data;

int main(void);

int main(void)
{
	PortAudioStream *stream;
	PaError err;
	
	printf("Wussup  PortAudio: Cosine Wave + Sine Wave, %.2f Hz.\n", FREQUENCY);

/* Initialize data for use by callback. */
	data.amplitude = 0.5;
	data.frequency = FREQUENCY;
        data.phase = 0.;

/* Initialize library before making any other calls. */
	err = Pa_Initialize();
	if( err != paNoError ) goto error;

/* Open an audio I/O stream. */
	err = Pa_OpenDefaultStream(
				&stream,
				0,              /* no input channels */
				2,              /* stereo output */
				paFloat32,      /* 32 bit floating point output */
				SAMPLE_RATE,
				BUFFER_SIZE,    /* frames per buffer */
				0,              /* number of buffers, if zero then use default minimum */
				cosineCallback,
				&data );
	if( err != paNoError ) goto error;

	err = Pa_StartStream( stream );
	if( err != paNoError ) goto error;

/* Sleep for several seconds. */
	Pa_Sleep(NUM_SECONDS*1000);

	err = Pa_StopStream( stream );
	if( err != paNoError ) goto error;

	err = Pa_CloseStream( stream );
	if( err != paNoError ) goto error;

	Pa_Terminate();
	printf("Calculated %ld samples.\n", data.count);
	printf("Finished.\n");
	return err;

error:
	Pa_Terminate();
	fprintf( stderr, "An error occured while using the portaudio stream.\n" ); 
	fprintf( stderr, "Error number: %d\n", err );
	fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
	return err;
}

    Source: geocities.com/rjpaho