#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <math.h>

using namespace std;

int main () 
{
	
	const int NUMBER_OF_SAMPLES = 128;
	float pi = 3.141592653589793238462643;
	float frequency;
	float gibbs;
	float sample;//The value of the sample.
	float sample_array[NUMBER_OF_SAMPLES];
	float sample_max;
	float sample_multiplier;
	
	//open file
	ofstream myFile;
	
	//This is the file the wavetable is going to show up in.
	myFile.open("SawtoothWavetable.txt");
	
	//int temp;
	int temp2;
	int output;
	float power;
	float tothepower;
	double a_frequency = 440;//The frequency of middle A.
	int partials;
	
	myFile << "const char G_AUC_SAWTOOTH_WAVETABLE_LUT [64][128] PROGMEM = ";
	myFile << "{";
	
	for (int i=-69;i <= 58; i++,i++)//127 midi notes, every other one
	{
		//	string binary;
		
		power = i/12.0;
		
		tothepower = pow(2, power);
		temp2 = a_frequency*tothepower;
		frequency = round(temp2);
		partials = 16000/frequency;
		
		myFile << "{";

		//We are taking 128 samples of the waveform.
		for(int t= 0; t < NUMBER_OF_SAMPLES; t++)
		{	
			sample = 0;
			
			//We sum the Fourier series for harmonics up to half the sample rate, the Nyquist frequency. 
			for(int s=1; s<=partials; s++)  
			{
				//The gibbs factor smooths out sharp transitions.
				gibbs = cos((float)(s-1)*pi/(2*(float)partials));
				gibbs *= gibbs;
				
				//this generates a sawtooth wavetable
				//sinx + 1/2sin2x + 1/3sin3x...
				sample += gibbs*(1/(float)s)*sin((float)s*2*pi*(float)t/NUMBER_OF_SAMPLES);
			}

			
			//We have to normalize the samples.  Make the highest sample = 1 by
			//finding the highest sample and multplying all values by the number
			//that makes the highest sample 255
			if(sample > sample_max)
			{
				sample_max = sample;
			}
			
			sample_array[t] = sample;

			
		}
		
		sample_multiplier = 1/sample_max;
		
		for(int p= 0; p < NUMBER_OF_SAMPLES; p++)
		{
			sample_array[p] = sample_array[p] * sample_multiplier;
			sample = sample_array[p];
			sample *= 127;
			sample += 127;
			sample = round(sample);
			
			if(sample <= 0)
			{
				sample = 0;
			}

			output = sample;

			myFile << sample;
			myFile << ",";
			
		}
		
		myFile << "},";
		myFile << endl;
		
		sample_max = 0;
		sample_multiplier = 0;
		
	}
	
	myFile << "};";
	
	//close connection to text file
	
	myFile.close();
	
	return 0;

}