#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// a*sin(b*(θ+c))+d+‥‥		cの単位は度(360)
// 11000Hzで録音
// 220Hzでの一振動は50カウント

unsigned char	*data;					/* SNDデータが入るとこ			*/
char	head[32];						/* SNDのヘッダー				*/
FILE 	*FP;							/* 書き込むファイル				*/
double	*para;							/* 計算のパラメータ				*/
double	*resl;							/* 計算結果						*/

void main( int argc, char *argv[] )
{
	int i,j,k,rep;
	double a,b,c,d,e,deg,tmp;
	double max=-10000,min=+10000;	/* 最大値=最小値=resl[0]になるように細工*/
	double leng;							/* (最大値−最小値)/225			*/
	
	printf( "／＼／＼／＼／＼／＼／＼波なみ〜〜〜〜〜〜〜〜〜〜〜〜\n");
	printf( "〜〜〜〜〜〜〜〜〜〜〜〜その１／＼／＼／＼／＼／＼／＼\n");
	printf( "△△△△△Ｂｙまつやぎつよべぇ(NIF:PEC02775)△△△△△\n\n");
	
	if( argc<8 || (argc-3)%5 !=0 )
	{
		printf("パラメータが少ないですよ。\n");
		printf("書式：run386 NAMINAMI.EXP 出力ﾌｧｲﾙ.SND  rep  a b c d e  a b c d e ‥‥\n");
		printf("b=1のとき(rep)回波が発生する（ファイルサイズ＝５０×rep）\n");
		printf("a*sin(b*(θ+cﾟ))+d\n");
		printf("e=0だと足し算\n");
		printf("e>0だとそれまでの数値を上回っていたときにその数値になる\n");
		printf("e<0だとそれまでの数値を下回っていたときにその数値になる\n\n");
		printf("またのご来店をお待ちしておりま〜す\n");
		exit(1);
	}
	
	rep=atoi(argv[2]);
	printf( "rep:%d\n",rep );					/* メモリーの確保	*/
	data=(unsigned char*)malloc(50*rep);
	resl=(double*)malloc(50*rep*sizeof(double));
	
	int par;
	par=(argc-3)/5;							/* sinの数						*/
	para=(double*)malloc(par*5*sizeof(double));
	for( i=3; i<argc; i++ )					/* 引数の読み込み				*/
		para[i-3]=atof(argv[i]);
	
	for( i=0; i<par; i++ )				/* 計算式の表示	*/
	{
		a=para[i*5+0];
		b=para[i*5+1];
		c=para[i*5+2];
		d=para[i*5+3];
		e=para[i*5+4];
		
		if( e==0 )
			printf( "(Add) %.2f*sin(%.2f*(θ%+.2fﾟ))%+.2f\n",a,b,c,d );
		if( e>0 )
			printf( "(Max) %.2f*sin(%.2f*(θ%+.2fﾟ))%+.2f\n",a,b,c,d );
		if( e<0 )
			printf( "(Min) %.2f*sin(%.2f*(θ%+.2fﾟ))%+.2f\n",a,b,c,d );
	}		
	
	for( j=0; j<50*rep; j++ )		/* rep回の振動を計算				*/
	{
		resl[j]=0;
		deg=(2*_PI)/50*j;			/* 角度に変換(単位:ラジアン)		*/
		for( k=0; k<par; k++ )		/* sinの数だけ計算					*/
		{
			a=para[k*5+0];
			b=para[k*5+1];
			c=(2*_PI)/360*para[k*5+2]; /* ディグリー＝＞ラジアンの変換	*/
			d=para[k*5+3];
			e=para[k*5+4];
			
			tmp=a*sin(b*(deg+c))+d;
			
			if( e==0 )	resl[j]+=tmp;	/* 足し算 */
			if( e>0 )   resl[j]=(resl[j]<tmp ? tmp:resl[j]); /* 上回ってる */
			if( e<0 )   resl[j]=(resl[j]>tmp ? tmp:resl[j]); /* 下回ってる */
		}
		if( resl[j]>max ) max=resl[j];	/* 最大値？ */
		if( resl[j]<min ) min=resl[j];	/* 最小値？ */
	}
	
	leng=(max-min)/255;
	
	for( i=0; i<50*rep; i++ )					/* SNDに出力できる様にする*/
	{
		j=(resl[i]-min)/leng;			/* double=>charの変換	*/
		if( j>127 ) data[i]=j;
		else	data[i]=127-j;
	}
	
	if((FP=fopen( argv[1], "wb" ))==NULL)
	{
		printf( "%sのオープンに失敗",argv[1]);
		exit(1);
	}
	
	strcpy( head, "naminami" );	/* サウンドネーム			*/
	for( i=0; i<4; i++ )
		head[i+8]=data[i];					/* サウンドID				*/
	*(int *)&head[12]=50*rep;				/* データ長					*/
	*(int *)&head[16]=0;					/* ループポイント			*/
	*(int *)&head[20]=50*rep;				/* ループ長					*/
	*(short int *)&head[24]=11000*0x62/1000;/* サンプリング周波数		*/
	*(short int *)&head[26]=0;				/* 原音の補正値				*/
	*(char *)&head[28]=57;					/* 原音の音階の設定			*/
	*(char *)&head[29]=0;					/* reserve					*/
	*(short int *)&head[30]=0;				/* reserve					*/
	
	fwrite( head, 32, 1, FP );
	fwrite( data, 50*rep, 1, FP );
	
	fclose( FP );
}
