#include <v_lib.h>

#define	SAMPLING_RATE	44100
#define	MAXTONES		256

u32_t	num_tones;
vec_t	phase[MAXTONES];
vec_t	dph[MAXTONES];
vec_t	amp[MAXTONES];
vec_t 	freq[MAXTONES];

vboolean __declspec(dllexport)	__stdcall
toneInit(vector_p fr,vector_p a)
{
	u32_t c;
	if(fr->size != a->size || fr->size > MAXTONES)
		return false;
	num_tones = fr->size;
	memCopy(freq,fr->elements,num_tones * sizeof(vec_t));
	memCopy(amp,a->elements,num_tones * sizeof(vec_t));
	memZero(phase,num_tones * sizeof(vec_t));
	for(c=0;c < num_tones;c++)
		dph[c] = M_2PI * freq[c] / (vec_t)SAMPLING_RATE;
	return true;
}

void __declspec(dllexport)	__stdcall
toneGenerate(vec_t *float_out,u32_t num_samples)
{
	u32_t s,c;
	vec_t out;
	for(s=0;s < num_samples;s++)
	{
		out = 0;
		for(c=0;c < num_tones;c++)
		{
			out += amp[c] * (vec_t)sin(phase[c]);
			phase[c] += dph[c];
		}
		if(out < -1)
			out = -1;
		else
			if(out > 1)
				out = 1;
		float_out[s] = out;
	}
}

#if 0

#define len	SAMPLING_RATE
vec_t 	buf[len];
s16_t	smp[len];

int main(int argc,char *argv[])
{
	u32_t t;
	int i;
	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	
	for(i=1;i<argc;i+=2)
	{
		if(!strToFloat(argv[i],&freq[num_tones]) || !strToFloat(argv[i+1],&amp[num_tones]))
			break;
		num_tones++;
	}

	conPrintf("parsed %d tones ...\n",num_tones);
	
	{
		u32_t c;
		for(c=0;c < num_tones;c++)
			dph[c] = M_2PI * freq[c] / (vec_t)SAMPLING_RATE;
    }
    
    t = timeTickCount();
	toneGenerate(buf,len);
	t = timeTickCount() - t;
	conPrintf("done: %u ms\n",t);

	{
		vhandle_t out;
		for(i=0;i<len;i++)
			smp[i] = (s16_t)(buf[i] * 0x7FFF);
		out = fileOpenWrite("out.raw");
		fileWrite(out,smp,2 * len);
		fileClose(out);
	}
	
	return 0;
}

#endif
