#include <wav.c>
#include <readconfig.c>
#include <rnd/explode.c>
#include <rnd/foreachfilein.c>
#include <rnd/fgetline.c>
#include <array_1d.c>
#include <rnd/Max.c>
#include <rnd/createdirchain.c>

LSet slows;

void applyconfig(const LSet conf)
{
	char *s=configget(conf,"Slow-down factor");
	char **e=explode(",",s); int n,m=explodesegs(e);
	slows=LSet(double); double x;
	for (n=0;n<m;n++)
	{
		x=atof(e[n]);
		LSet_add(&slows,&x);
	}
	explodefree(e);
}

typedef struct {REAL t,*x;} Record;

int Record_cmp(const Record *r,const Record *s)
{
	return (r->t>s->t)-(r->t<s->t);
}

void convertfile(const char *file,const char *dirto)
{
	char filename[200];
	strcpy(filename,strrchr(file,'\\')+1); filename[strlen(filename)-4]=0;
	LSet datas=LSet(Record);
	FILE *in=fopen(file,"rb"); int n,i,j,k,m;
	for (char *s;s=fgetline(in);free(s))
	{
		char **e=explode(",",s);
		if ((m=explodesegs(e))>=2)
		{
			Record r; r.t=atof(e[0]);
			r.x=array_1d(m-1);
			for (n=m-1;n>0;n--) r.x[n-1]=atof(e[n]);
			LSet_add(&datas,&r);
		}
		explodefree(e);
	}
	fclose(in);
	int colm=m-1;
	LSet_qsort(&datas,Record_cmp);
	Record *d=datas.a;
	double t,t0=d[0].t,t1=d[datas.m-1].t;
	char fileto[500]; const double samplerate=44100;
	for (i=slows.m-1;i>=0;i--)
	{
		double fac=((double *)slows.a)[i];
		for (j=colm-1;j>=0;j--)
		{
			if (colm==1) sprintf(fileto,"%s\\%lgx\\%s.wav",dirto,fac,filename);
			else sprintf(fileto,"%s\\%lgx\\%s-col%d.wav",dirto,fac,filename,1+j);
			printf("Converting file %s to %s\n",file,fileto);
			createdirchain(fileto,0);
			int samples=floor((t1-t0)*fac*samplerate)+1;
printf("%d samples (time = %lg, fac = %lgx)\n",samples,t1-t0,fac);
			double v,f,maxv=1e-20;
			for (n=datas.m-1;n>=0;n--) maxv=Max(maxv,fabs(d[n].x[j]));
			wav w=wavnew(samples,samplerate);
			for (n=k=0;n<samples;n++)
			{
				t=t0+(double)n/(fac*samplerate);
				while (k+1<datas.m && d[k+1].t<=t) k++;
				if (k+1<datas.m)
				{
					f=(t-d[k].t)/(d[k+1].t-d[k].t);
					v=(1.0-f)*d[k].x[j]+f*d[k+1].x[j];
				}
				else v=d[k].x[j];
				w.L[n]=w.R[n]=32767.0*v/maxv;
			}
			wavsave(w,fileto);
			wavfree(w);
		}
	}
	for (n=datas.m-1;n>=0;n--) array_1d_free(d[n].x);
	LSet_free(datas);
}

void convertdir(const char *dirfrom,const char *dirto)
{
	foreachfilein(dirfrom,convertfile,(void *)dirto);
}

void main(void)
{
	LSet conf=readconfig("config.txt");
	applyconfig(conf);
	freeconfig(conf);
	convertdir("input","output");
	printf("\nFinished!\n");
	getchar();
}

