/*H***************************************************************************** * * $Archive:: $ * $Revision:: $ * $Date:: $ * $Author:: $ * * DESCRIPTION: * This program contains the various functions for a sine wave * a square wave, a saw tooth, and a triangle wave. It also contains a * scaling function where zero is the minimum and a reverse function * * * GLOBALS * * PUBLIC FUNCTIONS: * * PRIVATE FUNCTIONS: * * USAGE/LIMITATIONS: * * NOTES: * * By: Patrick Cresap * *H***************************************************************************/ #define waveforms_c /*---- compilation control switches ----------------------------------------*/ /***************************************************************************** * INCLUDE FILES *****************************************************************************/ /*---- system and platform files -------------------------------------------*/ #include /*---- program files -------------------------------------------------------*/ /***************************************************************************** * EXTERNAL REFERENCE *****************************************************************************/ /*---- data declarations ---------------------------------------------------*/ #define SIN_TABLE_SIZE 256 extern unsigned short SineTable[SIN_TABLE_SIZE]; /*---- function prototypes -------------------------------------------------*/ /***************************************************************************** * PUBLIC DECLARATIONS *****************************************************************************/ /*---- data declarations ---------------------------------------------------*/ #define SIN_WAVE_POS 0x0000 #define SIN_WAVE_NEG 0x0001 unsigned short sin_wave_count = 0; unsigned short sin_section = SIN_WAVE_POS; /*---- InitSinTable --------------------------------------------------------*/ #define SIN_TABLE_SIZE 256 #define PI ( ( double )3.1415927 ) #define SINE_MAX_SCALE_FACTOR 0x7FFE double sined = 0; unsigned short SineTable[SIN_TABLE_SIZE]; #define MAX_VOLTAGE 0x7FFE #define MIN_VOLTAGE 0x8000 unsigned short square_wave_period = 100; unsigned short square_wave_count = 0; #define TRIANGLE_INCREASING_SLOPE 0x0001 #define TRIANGLE_DECREASING_SLOPE 0x0002 unsigned short triangle_dir = TRIANGLE_INCREASING_SLOPE; #define ZERO_VOLTAGE_NEG 0xFFFE #define ZERO_VOLTAGE_POS 0x0000 /***************************************************************************** * PRIVATE DECLARATIONS *****************************************************************************/ /*---- context -------------------------------------------------------------*/ /*---- data declarations ---------------------------------------------------*/ /*---- function prototypes -------------------------------------------------*/ /*---- macros --------------------------------------------------------------*/ /***************************************************************************** * PUBLIC FUNCTION DEFINITIONS *****************************************************************************/ /*F*************************************************************************** * NAME: unsigned short saw_wave ( unsigned short data ) * * DESCRIPTION: * creates a saw wave. * * NOTES: * *F***************************************************************************/ unsigned short saw_wave ( unsigned short data ) { /*-- this value determines the slope of the wave ----------------------*/ int saw_wave_inc = 0x80; data += saw_wave_inc; return data; } /*F*************************************************************************** * NAME: unsigned short square_wave ( unsigned short data ) * * DESCRIPTION: * creates a square wave * * NOTES: * *F***************************************************************************/ unsigned short square_wave ( unsigned short data ) { square_wave_count++; if ( square_wave_count == square_wave_period ) { if ( data == MIN_VOLTAGE ) { data = MAX_VOLTAGE; } else { data= MIN_VOLTAGE; } square_wave_count = 0; } return data; } /*F*************************************************************************** * NAME: unsigned short triangle_wave ( unsigned short data ) * * DESCRIPTION: * creates a triangle wave * * NOTES: * *F***************************************************************************/ unsigned short triangle_wave ( unsigned short data ) { /*-- the slope of the wave ---------------------------------------------*/ unsigned short triangle_wave_inc = 0x80; unsigned short temp; if ( data <= MAX_VOLTAGE ) { switch ( triangle_dir ) { case TRIANGLE_INCREASING_SLOPE: temp = data + triangle_wave_inc; if (temp > MAX_VOLTAGE) /* at peak */ { data = MAX_VOLTAGE; triangle_dir = TRIANGLE_DECREASING_SLOPE; } else { data = temp; } break; case TRIANGLE_DECREASING_SLOPE: if ( data < triangle_wave_inc ) { data = ZERO_VOLTAGE_NEG; triangle_dir = TRIANGLE_DECREASING_SLOPE; } else { data -= triangle_wave_inc; } break; default: break; } } else /* data > MIN_VOLTAGE */ { switch ( triangle_dir ) { case TRIANGLE_INCREASING_SLOPE: temp = data + triangle_wave_inc; if ( (ZERO_VOLTAGE_NEG - data) < triangle_wave_inc ) { data = ZERO_VOLTAGE_POS; triangle_dir = TRIANGLE_INCREASING_SLOPE; } else { data += triangle_wave_inc; } break; case TRIANGLE_DECREASING_SLOPE: temp = data - triangle_wave_inc; if ( temp < MIN_VOLTAGE ) /* at trough */ { triangle_dir = TRIANGLE_INCREASING_SLOPE; data = MIN_VOLTAGE; } else { data = temp; } break; default: break; } } return ( data ); } /*F*************************************************************************** * NAME: void Init_Sin_Table ( void ) * * DESCRIPTION: * Uses a predefined table of the positive half of a sine wave to create * a sin wave * * NOTES: * *F***************************************************************************/ void Init_Sin_Table ( void ) { unsigned short x =0; double increment= 0; double radian = 0; double ScaleSine = 0; for (x=0; x <= (SIN_TABLE_SIZE - 1); x++) { SineTable[x]=0; } increment = PI / SIN_TABLE_SIZE; for (x=0; x <= (SIN_TABLE_SIZE - 1); x++) { ScaleSine = sin(radian); SineTable[x] = ( unsigned short ) ( ScaleSine * SINE_MAX_SCALE_FACTOR); radian += increment; } } /*F*************************************************************************** * NAME: unsigned short sin_wave ( ) * * DESCRIPTION: * Uses a predefined table of the positive half of a sine wave to create * a sin wave * * NOTES: * *F***************************************************************************/ unsigned short sin_wave ( ) { unsigned short data; sin_wave_count++; /* after going through half of the sine wave (or through the entire sine * table), it switches over and does the other half of the sine wave. */ if (sin_wave_count == SIN_TABLE_SIZE) { sin_wave_count = 0; data = SineTable[SIN_TABLE_SIZE-1]; if (sin_section == SIN_WAVE_NEG) { sin_section = SIN_WAVE_POS; } else { sin_section = SIN_WAVE_NEG; } } /*-- produces the bottom or negative half of the sine wave -------------*/ else if (sin_section == SIN_WAVE_NEG) { data = SineTable[sin_wave_count]; data = 0xFFFE - data; } /*-- produces the top or positive half of the sine wave -------------*/ else { data = SineTable[sin_wave_count]; } data &= 0xFFFE; return data; } /*F*************************************************************************** * NAME: unsigned short reverse_zero_min_scale ( unsigned short data ) * * DESCRIPTION: * if the user wishes to use 0 as the minimum and 0xFFFE as the maximum, this * reverses the conversion from zer0_min_scale so that the user's values and * the codec values are seperated. * * NOTES: * reverses zero_min_scale *F***************************************************************************/ unsigned short reverse_zero_min_scale ( unsigned short data ) { if ( data >= 0x8000 ) { data = data + 0x8000; } else { data = data - 0x8000; } return data; } /*F*************************************************************************** * NAME: unsigned short zero_min_scale ( unsigned short data ) * * DESCRIPTION: * if the user wishes to use 0 as the minimum and 0xFFFE as the maximum, this * will convert the value to the proper codec values * * NOTES: * to reverse it, use reverse_zero_min_scale *F***************************************************************************/ unsigned short zero_min_scale ( unsigned short data ) { if ( data >= 0x8000 ) { data = data - 0x8000; } else { data = data + 0x8000; } return data; }