const int ayvoltab[256]={
	0,1,1,2,3,3,4,4,4,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,
		10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
		11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
		12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
		13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
		14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
		14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,
		15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
};


#ifndef PI
#define PI	3.141592654f
#endif


inline float Goertzel(short int *x, int N, float frequency)
{
    float Skn, Skn1, Skn2;
    Skn = Skn1 = Skn2 = 0;
	
    float ff,cf,dcf;//это можно посчитать для каждой из возможных частот заранее
    ff=2*PI*frequency/44100.0f;
    cf=cos(ff);
	dcf=cf*2;
	
    for (int i=0; i<N; i++)
    {
		Skn2 = Skn1;
		Skn1 = Skn;
		Skn = dcf*Skn1 - Skn2 + float(x[i]);
    }
    
    float WNk = exp(-ff); // this one ignores complex stuff
    //float WNk = exp(-2*j*PI*k/N);
    return (Skn - WNk*Skn1);
}




bool FindSign(unsigned char *data,int &ptr,int size,const char *sign)
{
	unsigned int aa,len;
	
	len=strlen(sign);
	
	for(aa=0;aa<size-len;aa++)
	{
		if(!memcmp(&data[aa],sign,len))
		{
			ptr=aa;
			return true;
		}
	}
	return false;
}



bool ImportWAV(int fxn,const char *filename)
{
	FILE *file;
	unsigned char *data;
	int aa,bb,size,ptr,pd;
	int origlen,samples,chans,bits,rate;
	int smp,ifrq,icnt;
	short int *wavdata;
	int min,max,sz,mfrq;
	float muln,amp,mamp;
	float fpp,fstep;
	
	bool normalize=true;
	bool prenormalize=true;
	
	file=fopen(filename,"rb");
	if(!file) return false;
	fseek(file,0,SEEK_END);
	size=ftell(file);
	fseek(file,0,SEEK_SET);
	data=(unsigned char*)malloc(size);
	fread(data,size,1,file);
	fclose(file);
	
	//парсинг заголовка
	
	ptr=0;
	
	if(!FindSign(data,ptr,size,"RIFF"))
	{
		Application->MessageBox("This is not WAVE file","Error",MB_OK);
		free(data);
		return false;
	}
	
	ptr+=4;
	if(!FindSign(data,ptr,size,"WAVEfmt "))
	{
		Application->MessageBox("This is not WAVE file","Error",MB_OK);
		free(data);
		return false;
	}
	
	if(RdWordLH(&data[ptr+12])!=1)
	{
		Application->MessageBox("Only unpacked PCM files supported","Error",MB_OK);
		free(data);
		return false;
	}
	
	chans=RdWordLH(&data[ptr+14]);
	rate=RdDWordLH(&data[ptr+16]);
	bits=RdWordLH(&data[ptr+26]);
	
	if(bits!=8&&bits!=16)
	{
		Application->MessageBox("Only 8/16bit samples supported","Error",MB_OK);
		free(data);
		return false;
	}
	
	ptr+=28;
	
	if(!FindSign(data,ptr,size,"data"))
	{
		Application->MessageBox("No DATA chunk in file","Error",MB_OK);
		free(data);
		return false;
	}
	
	origlen=RdDWordLH(&data[ptr+4])/(bits>>3);
	ptr+=8;
	
	
	//пока нехватает интерполяции при ресемплинге
	
	samples=(int)(float(origlen)/float(rate)*44100.0f);
	
	wavdata=(short int*)malloc(samples*sizeof(short int));
	
	fpp=ptr;
	ptr=-1;
	fstep=float(origlen)/float(samples);
	
	min=0;
	max=0;
	
	if(bits==8)
	{
		for(aa=0;aa<samples;aa++)
		{
			pd=int(fpp);
			if(pd!=ptr)
			{
				ptr=pd;
				smp=0;
				for(bb=0;bb<chans;bb++)
				{
					smp+=((int(data[ptr+bb])-128)<<8);
				}
				smp/=chans;
				if(smp>max) max=smp;
				if(smp<min) min=smp;
			}
			wavdata[aa]=smp;
			fpp+=fstep;
		}
	}
	else
	{
		for(aa=0;aa<samples;aa++)
		{
			pd=int(fpp);
			if(pd!=ptr)
			{
				ptr=pd<<1;
				smp=0;
				for(bb=0;bb<(chans<<1);bb+=2)
				{
					smp+=((short int)RdWordLH(&data[ptr+bb]));
				}
				ptr=pd;
				smp/=chans;
				if(smp>max) max=smp;
				if(smp<min) min=smp;
			}
			wavdata[aa]=smp;
			fpp+=fstep;
		}
	}
	
	free(data);
	
	
	if(prenormalize)
	{
		if(max-min>0) muln=65535.0f/float(max-min); else muln=1.0f;
		for(aa=0;aa<samples;aa++)
		{
			wavdata[aa]=(short int)(float(wavdata[aa])*muln);
		}
    }
    
	
	//как проанализировать частоты..
	//нужно пройтись по всему сигналу шагами в 1/50 секунды
	//для каждого составить табличку из 4096 значений амплитуды, для каждой из частот
	//в табличке ищется максимальное значение, индекс таблички = значение делителя
	
	//есть проблема с неравномерностью анализируемых частот - слишком много низких, а это нафиг не нужно
	
	
	//конверсия
	EffectInit(fxn);
	
	
	pd=0;
	for(aa=0;aa<samples;aa+=(44100/50))
	{
		sz=44100/50*2;
		if(aa+sz>=samples) sz=samples-aa;
		
		mamp=0;
		mfrq=4095;
		//1773400/16 = 110837hz, т.е. шибко дохера
		//1773400/16/4095 = 27hz
		//соотв. минимальный делитель будет 6, 18472hz (меньше - выше Fdisc/2)
		for(bb=6;bb<4096;bb+=1)
		{
			amp=Goertzel(&wavdata[aa],sz,1773400/8/bb);
			if(amp>mamp)
			{
				mamp=amp;
				mfrq=bb;
			}
		}
		
		//всё, в mfrq требуемый делитель
		ayBank[fxn].ayEffect[pd].noise=mfrq>>7;
		ayBank[fxn].ayEffect[pd++].tone=mfrq;
		
	}         
	
	
	
	if(normalize)
	{
		max=1;
		
		for(aa=0;aa<samples;aa+=(44100/50))
		{
			smp=0;
			for(bb=aa;bb<(aa+44100/50);bb++) smp+=abs(wavdata[bb]);
			smp=smp/(44100/50);
			if(smp>max) max=smp;
		}
		
		muln=32768.0f/float(max);
	}
	else
	{
		muln=1.0f;
	}
	
	pd=0;
	
	for(aa=0;aa<samples;aa+=(44100/50))
	{
        smp=0;
        for(bb=aa;bb<(aa+44100/50);bb++) smp+=abs(wavdata[bb]);
		
		smp=smp/(44100/50);
		smp=(int)(float(smp)*muln);
        smp>>=7;
		if(smp>255) smp=255;
		
		ayBank[fxn].ayEffect[pd].t=true;
		ayBank[fxn].ayEffect[pd++].volume=ayvoltab[smp];
		
		if(pd>=max_fx_len) break;
	}
	
	free(wavdata);
	
	strcpy(ayBank[fxn].name,NameTrimPath(filename).c_str());
	
	return true;
}