#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <file_dlg.h>
#include <egb.h>
#include <mos.h>
#include <snd.h>
#include "otohime.h"
#include "otolib.h"

/* echo */
int	echoDialogId = -1 ;
int	echoOkBtnId = -1 ;
int	echoPlayBtnId = -1 ;
int	echoUndoBtnId = -1 ;
int	echoInfBtnId = -1 ;
int	echoCanBtnId = -1 ;
int	echoMesId[32] = -1 ;
int	echoSubDialogId = -1 ;
int	echoDelayVolumeId = -1 ;
int	echoDelayNumId = -1 ;
int	echoMainMixVolumeId = -1 ;
int	echoMainMixNumId = -1 ;
int	echoDelayMixVolumeId = -1 ;
int	echoDelayMixNumId = -1 ;
int	echoDecVolumeId = -1 ;
int	echoDecNumId = -1 ;
int	echoCountNumId = -1 ;
int	echoAfterNumId = -1 ;

/* phase */
int	phaseDialogId = -1 ;
int	phaseOkBtnId = -1 ;
int	phasePlayBtnId = -1 ;
int	phaseUndoBtnId = -1 ;
int	phaseInfBtnId = -1 ;
int	phaseCanBtnId = -1 ;
int	phaseMesId[30] = -1 ;
int	phaseSubDialogId = -1 ;
int	phaseDelayNumId = -1 ;
int	phaseMainMixVolumeId = -1 ;
int	phaseDelayMixVolumeId = -1 ;
int	phaseModu1NumId = -1 ;
int	phaseSpeed1NumId = -1 ;
int	phaseStart1NumId = -1 ;
int	phaseModu2NumId = -1 ;
int	phaseSpeed2NumId = -1 ;
int	phaseStart2NumId = -1 ;
int	phaseDelayVolumeId = -1 ;
int	phaseMainMixNumId = -1 ;
int	phaseDelayMixNumId = -1 ;

/* vibrato */
int	vibraDialogId = -1 ;
int	vibraOkBtnId = -1 ;
int	vibraPlayBtnId = -1 ;
int	vibraUndoBtnId = -1 ;
int	vibraInfBtnId = -1 ;
int	vibraCanBtnId = -1 ;
int	vibraMesId[19] = -1 ;
int	vibraSubDialogId = -1 ;
int	vibraMainMixVolumeId = -1 ;
int	vibraMainMixNumId = -1 ;
int	vibraDelayMixVolumeId = -1 ;
int	vibraDelayMixNumId = -1 ;
int	vibraModu1NumId = -1 ;
int	vibraStart1NumId = -1 ;
int	vibraModu2NumId = -1 ;
int	vibraSpeed2NumId = -1 ;
int	vibraStart2NumId = -1 ;
int	vibraSpeed1NumId = -1 ;

/* tremolo */
int	tremoDialogId = -1 ;
int	tremoOkBtnId = -1 ;
int	tremoPlayBtnId = -1 ;
int	tremoUndoBtnId = -1 ;
int	tremoInfBtnId = -1 ;
int	tremoCanBtnId = -1 ;
int	tremoMesId[18] = -1 ;
int	tremoSubDialogId = -1 ;
int	tremoMainMixVolumeId = -1 ;
int	tremoMainMixNumId = -1 ;
int	tremoTremoMixVolumeId = -1 ;
int	tremoTremoMixNumId = -1 ;
int	tremoSpeedNumId = -1 ;
int	tremoSpeedVolumeId = -1 ;


/* ECHO */

int	sndEffectEcho()
{
	MMI_SendMessage( echoDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( echoDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( echoDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( echoDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTECH:echoOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	echoOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head ;
	int	var, min, max, delta, ptColumn ;
	int delay, mainmix, delmix, decrate, count, after, f ;
	int ret ;

	setMsgColor( echoMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;
	f = ( head->freq ) * 1000 / 0x62 ;				/* freq */
	f = ( f + 50 )/100 * 100 ;				/* 10の位を四捨五入 */

	MMI_SendMessage( echoDelayNumId, MM_GETNUMBOX, 5,	/* delay */
						&var, &min, &max, &delta, &ptColumn ) ;
	delay = f * var / 1000 ;

	MMI_SendMessage( echoMainMixNumId, MM_GETNUMBOX, 5,	/* main mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	mainmix = var * 256 / 100 ;

	MMI_SendMessage( echoDelayMixNumId, MM_GETNUMBOX, 5,	/* delay mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	delmix = var * 256 / 100 ;

	MMI_SendMessage( echoDecNumId, MM_GETNUMBOX, 5,	/* 減衰率 */
						&var, &min, &max, &delta, &ptColumn ) ;
	decrate = var * 256 / 100 ;

	MMI_SendMessage( echoCountNumId, MM_GETNUMBOX, 5,	/* 減衰率 */
						&var, &min, &max, &delta, &ptColumn ) ;
	count = var ;

	MMI_SendMessage( echoAfterNumId, MM_GETNUMBOX, 5,	/* 余韻 */
						&var, &min, &max, &delta, &ptColumn ) ;
	after = f * var / 1000 ;

//	if( ( 32 + (head->length) + after ) > sndBufSize )
//		after = sndBufSize - 32 - (head->length) ;

	ret = sndEcho( delay, mainmix, delmix, decrate, count, after ) ;
	if( ret )
		errorCheck( ret ) ;

	setMsgColor( echoMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTECH:echoPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	echoPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( echoMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( echoMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTECH:echoUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	echoUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( echoMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( echoMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTECH:echoInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	echoInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( echoDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( echoDialogId, (~MS_DSPONLYL40) ) ;
	return NOERR ;
}

/*	initDataIOTECH:echoCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	echoCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTECH:echoDelayVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTECH:echoDelayNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	echoDelaySet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ボリュームは1/2 */

	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == echoDelayVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoDelayNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoDelayNumId, MM_SETNUMBOX, 5,
							var*2, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( echoDelayNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == echoDelayNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoDelayVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		if( var2 > 500 )var2 = 500 ;
		MMI_SendMessage( echoDelayVolumeId, MM_SETSCROLL, 5,
										var2/2, min, max, len, page ) ;
		MMI_SendMessage( echoDelayVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTECH:echoMainMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTECH:echoMainMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	echoMainMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == echoMainMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoMainMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoMainMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( echoMainMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == echoMainMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoMainMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoMainMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( echoMainMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTECH:echoDelayMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTECH:echoDelayMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	echoDelayMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == echoDelayMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoDelayMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoDelayMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( echoDelayMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == echoDelayMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoDelayMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoDelayMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( echoDelayMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTECH:echoDecVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTECH:echoDecNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	echoDecSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == echoDecVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoDecNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoDecNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( echoDecNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == echoDecNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( echoDecVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( echoDecVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( echoDecVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/*	PHASE */

int	sndEffectPhaseShift()
{
	MMI_SendMessage( phaseDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( phaseDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( phaseDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( phaseDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTPHA:phasePlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	phasePlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( phaseMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( phaseMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTPHA:phaseOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	phaseOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head ;
	char para[64] ;
	char work[512] ;
	int	var, min, max, delta, ptColumn ;

	setMsgColor( phaseMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;

	DWORD( para + 0 ) = 0 ;
	MMI_SendMessage( phaseDelayNumId, MM_GETNUMBOX, 5,	/* delay */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 4 ) = var ;
	MMI_SendMessage( phaseMainMixNumId, MM_GETNUMBOX, 5,	/* main mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 8 ) = var * 256 / 100 ;
	MMI_SendMessage( phaseDelayMixNumId, MM_GETNUMBOX, 5,	/* delay mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 12 ) = var * 256 / 100 ;
	MMI_SendMessage( phaseModu1NumId, MM_GETNUMBOX, 5,		/* modu1 */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 16 ) = var ;
	MMI_SendMessage( phaseSpeed1NumId, MM_GETNUMBOX, 5,		/* speed1 */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 20 )
	= (double)var / 100 * 65536 * 4 / (head->freq * 1000 / 0x62) ;

	MMI_SendMessage( phaseStart1NumId, MM_GETNUMBOX, 5,		/* start1 */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 24 ) = var * 65536 / 90 + 65535*3 ;

	MMI_SendMessage( phaseModu2NumId, MM_GETNUMBOX, 5,		/* modu2 */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 28 ) = var ;
	MMI_SendMessage( phaseSpeed2NumId, MM_GETNUMBOX, 5,		/* speed2 */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 32 )
	= (double)var / 100 * 65536 * 4 / (head->freq * 1000 / 0x62) ;

	MMI_SendMessage( phaseStart2NumId, MM_GETNUMBOX, 5,		/* start2 */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 36 ) = var * 65536 / 90 + 65535*3 ;

	sndPhaseDelay( sndBuf2, sndBuf1, para, work ) ;

	setMsgColor( phaseMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTPHA:phaseCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	phaseCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTPHA:phaseDelayNumId:MJ_NUMBOXL40の呼び出し関数	*/
/*	initDataIOTPHA:phaseDelayVolumeId:MJ_SCRLL40の呼び出し関数	*/
int	phaseDelaySet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* vol.は実際の数値の1/2 */

	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == phaseDelayVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( phaseDelayNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( phaseDelayNumId, MM_SETNUMBOX, 5,
							var*2, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( phaseDelayNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == phaseDelayNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( phaseDelayVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( phaseDelayVolumeId, MM_SETSCROLL, 5,
										var2/2, min, max, len, page ) ;
		MMI_SendMessage( phaseDelayVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTPHA:phaseMainMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTPHA:phaseMainMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	phaseMainMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == phaseMainMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( phaseMainMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( phaseMainMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( phaseMainMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == phaseMainMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( phaseMainMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( phaseMainMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( phaseMainMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTPHA:phaseDelayMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTPHA:phaseDelayMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	phaseDelayMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == phaseDelayMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( phaseDelayMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( phaseDelayMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( phaseDelayMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == phaseDelayMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( phaseDelayMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( phaseDelayMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( phaseDelayMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTPHA:phaseUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	phaseUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( phaseMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( phaseMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTPHA:phaseInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	phaseInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( phaseDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( phaseDialogId, (~MS_DSPONLYL40) ) ;
	return NOERR ;
}


/* VIBRATO */

int	sndEffectVibrato()
{
	MMI_SendMessage( vibraDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( vibraDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( vibraDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( vibraDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTVIB:vibraOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	vibraOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head ;
	char para[64] ;
	char work[512] ;
	int	var, min, max, delta, ptColumn ;
	int modu1, modu2 ;
	int d, f, s ;

	setMsgColor( vibraMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;

	MMI_SendMessage( vibraMainMixNumId, MM_GETNUMBOX, 5,	/* main mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 8 ) = var * 256 / 100 ;
	MMI_SendMessage( vibraDelayMixNumId, MM_GETNUMBOX, 5,	/* delay mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 12 ) = var * 256 / 100 ;
	MMI_SendMessage( vibraModu1NumId, MM_GETNUMBOX, 5,		/* modu1 */
						&var, &min, &max, &delta, &ptColumn ) ;
	d = var ;
	MMI_SendMessage( vibraSpeed1NumId, MM_GETNUMBOX, 5,		/* speed1 */
						&var, &min, &max, &delta, &ptColumn ) ;
	f = var ;
	MMI_SendMessage( vibraStart1NumId, MM_GETNUMBOX, 5,		/* start1 */
						&var, &min, &max, &delta, &ptColumn ) ;
	s = var ;
	modu1 = .05946 * (head->freq * 1000 / 0x62) * d
										 / ( 2 * 3.14 * f / 10 * 100 ) ;
	DWORD( para + 16 ) = modu1 ;
	DWORD( para + 20 )
	= (double)f / 10 * 65535 * 4 / (head->freq * 1000 / 0x62) ;
	DWORD( para + 24 ) = 65536 * s / 90 + 65536 * 3 ;	/* 270°先送り */



	MMI_SendMessage( vibraModu2NumId, MM_GETNUMBOX, 5,		/* modu2 */
						&var, &min, &max, &delta, &ptColumn ) ;
	d = var ;
	MMI_SendMessage( vibraSpeed2NumId, MM_GETNUMBOX, 5,		/* speed2 */
						&var, &min, &max, &delta, &ptColumn ) ;
	f = var ;
	MMI_SendMessage( vibraStart2NumId, MM_GETNUMBOX, 5,		/* start2 */
						&var, &min, &max, &delta, &ptColumn ) ;
	s = var ;
	modu2 = .05946 * (head->freq * 1000 / 0x62) * d
										 / ( 2 * 3.14 * f / 10 * 100 ) ;
	DWORD( para + 28 ) = modu2 ;
	DWORD( para + 32 )
	= (double)f / 10 * 65535 * 4 / (head->freq * 1000 / 0x62) ;
	DWORD( para + 36 ) = 65536 * s / 90 + 65536 * 3 ;	/* 270°先送り */

	DWORD( para + 0 ) = 0 ;								/* main delay */
	DWORD( para + 4 ) = modu1 + modu2 ;					/* phase delay */

	sndPhaseDelay( sndBuf2, sndBuf1, para, work ) ;

	setMsgColor( vibraMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTVIB:vibraPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	vibraPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( vibraMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( vibraMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTVIB:vibraUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	vibraUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( vibraMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( vibraMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTVIB:vibraInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	vibraInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( vibraDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( vibraDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTVIB:vibraCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	vibraCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTVIB:vibraMainMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTVIB:vibraMainMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	vibraMainMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == vibraMainMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( vibraMainMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( vibraMainMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( vibraMainMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == vibraMainMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( vibraMainMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( vibraMainMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( vibraMainMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTVIB:vibraDelayMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTVIB:vibraDelayMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	vibraDelayMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == vibraDelayMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( vibraDelayMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( vibraDelayMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( vibraDelayMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == vibraDelayMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( vibraDelayMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( vibraDelayMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( vibraDelayMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* TREMOLO */

int	sndEffectTremolo()
{
	MMI_SendMessage( tremoDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( tremoDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( tremoDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( tremoDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTTRE:tremoOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	tremoOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head ;
	char para[64] ;
	char work[512] ;
	int	var, min, max, delta, ptColumn ;

	setMsgColor( tremoMesId[0], EXE_COLOR ) ;

	unDo() ;

	head = (SNDHEAD *)sndBuf2 ;

	MMI_SendMessage( tremoMainMixNumId, MM_GETNUMBOX, 5,	/* main mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 0 ) = var * 256 / 100 ;
	MMI_SendMessage( tremoTremoMixNumId, MM_GETNUMBOX, 5,	/* tremo mix */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 4 ) = var * 256 / 100 ;
	MMI_SendMessage( tremoSpeedNumId, MM_GETNUMBOX, 5,		/* speed */
						&var, &min, &max, &delta, &ptColumn ) ;
	DWORD( para + 8 )
	= (double)var / 10 * 65536 * 4 / (head->freq * 1000 / 0x62) ;

	DWORD( para + 12 ) = 0 ;

	sndTremolo( sndBuf1, para, work ) ;

	setMsgColor( tremoMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTTRE:tremoPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	tremoPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( tremoMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( tremoMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTTRE:tremoUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	tremoUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( tremoMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( tremoMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTTRE:tremoInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	tremoInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( tremoDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( tremoDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTTRE:tremoCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	tremoCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTTRE:tremoMainMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTTRE:tremoMainMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	tremoMainMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == tremoMainMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( tremoMainMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( tremoMainMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( tremoMainMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == tremoMainMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( tremoMainMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( tremoMainMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( tremoMainMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTTRE:tremoTremoMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTTRE:tremoTremoMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	tremoTremoMixSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == tremoTremoMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( tremoTremoMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( tremoTremoMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( tremoTremoMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == tremoTremoMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( tremoTremoMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( tremoTremoMixVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( tremoTremoMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTTRE:tremoSpeedNumId:MJ_NUMBOXL40の呼び出し関数	*/
/*	initDataIOTTRE:tremoSpeedVolumeId:MJ_SCRLL40の呼び出し関数	*/
int	tremoSpeedSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ボリュームは1/2 */

	int	var, min, max, len, page ;			/* スクロールの変数 */
	int	var2, min2, max2, delta2, ptColumn2 ;	/* 数値設定の変数 */

	if( kobj == tremoSpeedVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( tremoSpeedNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( tremoSpeedNumId, MM_SETNUMBOX, 5,
							var*2, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( tremoSpeedNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == tremoSpeedNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( tremoSpeedVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( tremoSpeedVolumeId, MM_SETSCROLL, 5,
										var2/2, min, max, len, page ) ;
		MMI_SendMessage( tremoSpeedVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* これ以後は, このソースのＣによる音声処理ルーチン */

/***** エコールーチン *****/
/* 遅れ, ﾒｲﾝmixrate, 初期減衰率, 減衰率, 減衰処理count, 余韻バイト数 */
/* rateや率は0〜256 */
sndEcho( delay, mrate, fdec, dec, count, after )
int delay ;
int mrate ;
int fdec ;
int dec ;
int count ;
int after ;
{
	SNDHEAD *head1, *head2 ;

	int i, j ;
	int len0, len1 ;
	int del, d, x ;
	char *source, *new ;
	int decr[101] ;

	head1 = (SNDHEAD *)sndBuf1 ;
	head2 = (SNDHEAD *)sndBuf2 ;

	len0 = head2->length ;
	len1 = len0 + after ;	/* after = 余韻 */
	if( len1 > sndBufSize-32 )
		return OUT_OF_MEMORY ;

	head1->length = len1 ;
	source = sndBuf2 + 32 ;
	new = sndBuf1 + 32 ;

	if( count > 100 )
		count = 100 ;
	decr[1] = fdec ;
	for( i=2 ; i<=count ; i++ )
	{
		decr[i] = ( decr[i-1] * dec ) >> 8 ;
	}

	for( i=0 ; i<len1 ; i++ )
	{
		del = 0 ;
		for( j=1 ; j<=count ; j++ )
		{
			if( (i-delay*j >= 0) && (i-delay*j < len0) )
			{
				d = source[i-delay*j] ;
				d &= 0xff ;
				if( d >= 128 )
					d = 128 - d ;
				d = d * decr[j] ;
				del += d ;
			}
		}

		x = 0 ;
		if( i < len0 )
		{
			x = source[i] ;
			x &= 0xff ;
			if( x >= 128 )
				x = 128 - x ;
			x = x * mrate ;
		}
		x = ( x + del ) >> 8 ;
		if( x <= 0 )
		{
			x = 128 - x ;
			if( x > 254 )
				x = 254 ;
		}
		else if( x > 127 )
			x = 127 ;

		new[i] = x ;
	}

	return NOERR ;
}


