#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 <math.h>
#include "otohime.h"
#include "otolib.h"

/* voice change */
int	voicDialogId = -1 ;
int	voicOkBtnId = -1 ;
int	voicPlayBtnId = -1 ;
int	voicUndoBtnId = -1 ;
int	voicInfBtnId = -1 ;
int	voicCanBtnId = -1 ;
int	voicMesId[24] = -1 ;
int	voicSubDialogId = -1 ;
int	voicMulVolumeId = -1 ;
int	voicMulNumId = -1 ;
int	voicCycleNumId = -1 ;
int	voicCrossNumId = -1 ;

/* harmony */
int	harmDialogId = -1 ;
int	harmOkBtnId = -1 ;
int	harmPlayBtnId = -1 ;
int	harmUndoBtnId = -1 ;
int	harmInfBtnId = -1 ;
int	harmCanBtnId = -1 ;
int	harmMesId[27] = -1 ;
int	harmSubDialogId = -1 ;
int	harmMainMixVolumeId = -1 ;
int	harmMainMixNumId = -1 ;
int	harmSubMixVolumeId = -1 ;
int	harmSubMixNumId = -1 ;
int	harmMulVolumeId = -1 ;
int	harmMulNumId = -1 ;
int	harmCycleNumId = -1 ;
int	harmCrossNumId = -1 ;

/* expander */
int	expDialogId = -1 ;
int	expOkBtnId = -1 ;
int	expPlayBtnId = -1 ;
int	expUndoBtnId = -1 ;
int	expInfBtnId = -1 ;
int	expCanBtnId = -1 ;
int	expMesId[23] = -1 ;
int	expSubDialogId = -1 ;
int	expMulVolumeId = -1 ;
int	expMulNumId = -1 ;
int	expCycleNumId = -1 ;
int	expCrossNumId = -1 ;

/* level */
int	levelDialogId = -1 ;
int	levelOkBtnId = -1 ;
int	levelPlayBtnId = -1 ;
int	levelUndoBtnId = -1 ;
int	levelInfBtnId = -1 ;
int	levelCanBtnId = -1 ;
int	levelMesId[19] = -1 ;
int	levelSubDialogId = -1 ;
int	levelMulVolumeId = -1 ;
int	levelMulNumId = -1 ;

/* pitch */
int	pitchDialogId = -1 ;
int	pitchOkBtnId = -1 ;
int	pitchPlayBtnId = -1 ;
int	pitchUndoBtnId = -1 ;
int	pitchInfBtnId = -1 ;
int	pitchCanBtnId = -1 ;
int	pitchMesId[20] = -1 ;
int	pitchSubDialogId = -1 ;
int	pitchMulVolumeId = -1 ;
int	pitchMulNumId = -1 ;

/* sampling rate set */
int	sampDialogId = -1 ;
int	sampOkBtnId = -1 ;
int	sampPlayBtnId = -1 ;
int	sampUndoBtnId = -1 ;
int	sampCanBtnId = -1 ;
int	sampMesId[7] = -1 ;
int	sampSubDialogId = -1 ;
int	sampRateNumId = -1 ;
int	sampInfBtnId = -1 ;


/* VOICE CHANGE */

int	sndEffectVoiceChange()
{
	MMI_SendMessage( voicDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( voicDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( voicDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( voicDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTVOI:voicOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	voicOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head ;

	int	var, min, max, delta, ptColumn ;
	int f, t, mul, c ;
	int ret ;

	setMsgColor( voicMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;
	f = ( head->freq ) * 1000 / 0x62 ;				/* freq */
	f = ( f + 50 )/100 * 100 ;				/* 10の位を四捨五入 */

	MMI_SendMessage( voicCycleNumId, MM_GETNUMBOX, 5,	/* 分割周期 */
						&var, &min, &max, &delta, &ptColumn ) ;
	t = f * var / 1000 ;

	MMI_SendMessage( voicMulNumId, MM_GETNUMBOX, 5,		/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul = pow( 2.0, ( (double)var ) /1200 ) * 65536 ;

	MMI_SendMessage( voicCrossNumId, MM_GETNUMBOX, 5,	/* cross over */
						&var, &min, &max, &delta, &ptColumn ) ;
	c = t * var / 100 ;

	ret = sndVoiceChng( mul, t, c ) ;
	if( ret )
		errorCheck( ret ) ;

	setMsgColor( voicMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTVOI:voicPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	voicPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( voicMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( voicMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTVOI:voicUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	voicUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( voicMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( voicMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTVOI:voicInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	voicInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( voicDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( voicDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTVOI:voicCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	voicCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTVOI:voicMulVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTVOI:voicMulNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	voicMulSet(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 ;	/* 数値設定の変数 */

	/* volumeの方は実際の値の1/10 */

	if( kobj == voicMulVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( voicMulNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( voicMulNumId, MM_SETNUMBOX, 5,
							var*10, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( voicMulNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == voicMulNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( voicMulVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( voicMulVolumeId, MM_SETSCROLL, 5,
										var2/10, min, max, len, page ) ;
		MMI_SendMessage( voicMulVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* HARMONY */

int	sndEffectHarmony()
{
	MMI_SendMessage( harmDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( harmDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( harmDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( harmDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTHAR:harmOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	harmOkchk(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 f, t, mul, c ;
	int ret ;

	setMsgColor( harmMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;
	f = ( head->freq ) * 1000 / 0x62 ;				/* freq */
	f = ( f + 50 )/100 * 100 ;				/* 10の位を四捨五入 */

	MMI_SendMessage( harmCycleNumId, MM_GETNUMBOX, 5,	/* 分割周期 */
						&var, &min, &max, &delta, &ptColumn ) ;
	t = f * var / 1000 ;

	MMI_SendMessage( harmMulNumId, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul = pow( 2.0, ( (double)var ) /1200 ) * 65536 ;

	MMI_SendMessage( harmCrossNumId, MM_GETNUMBOX, 5,	/* cross over */
						&var, &min, &max, &delta, &ptColumn ) ;
	c = t * var / 100 ;

	ret = sndVoiceChng( mul, t, c ) ;

	/* mix */

	if( ret )
		errorCheck( ret ) ;
	else
	{
		MMI_SendMessage( harmMainMixNumId, MM_GETNUMBOX, 5,
						&var, &min, &max, &delta, &ptColumn ) ;
		DWORD( para + 0 ) = var * 256 / 100 ;
		MMI_SendMessage( harmSubMixNumId, MM_GETNUMBOX, 5,
						&var, &min, &max, &delta, &ptColumn ) ;
		DWORD( para + 4 ) = var * 256 / 100 ;
		DWORD( para + 8 ) = sndBufSize ;

		sndMixTrans( sndBuf2, sndBuf1, para, work ) ;
	}

	setMsgColor( harmMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTHAR:harmPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	harmPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( harmMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( harmMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTHAR:harmUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	harmUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( harmMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( harmMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTHAR:harmInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	harmInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( harmDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( harmDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTHAR:harmCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	harmCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTHAR:harmMulVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTHAR:harmMulNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	harmMulSet(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 ;	/* 数値設定の変数 */

	/* volumeの方は実際の値の1/10 */

	if( kobj == harmMulVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( harmMulNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( harmMulNumId, MM_SETNUMBOX, 5,
							var*10, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( harmMulNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == harmMulNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( harmMulVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( harmMulVolumeId, MM_SETSCROLL, 5,
										var2/10, min, max, len, page ) ;
		MMI_SendMessage( harmMulVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTHAR:harmMainMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTHAR:harmMainMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	harmMainMixSet(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 == harmMainMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( harmMainMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( harmMainMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( harmMainMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == harmMainMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( harmMainMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( harmMainMixVolumeId, MM_SETSCROLL, 5,
										var, min, max, len, page ) ;
		MMI_SendMessage( harmMainMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTHAR:harmSubMixVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTHAR:harmSubMixNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	harmSubMixSet(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 == harmSubMixVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( harmSubMixNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( harmSubMixNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( harmSubMixNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == harmSubMixNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( harmSubMixVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( harmSubMixVolumeId, MM_SETSCROLL, 5,
										var, min, max, len, page ) ;
		MMI_SendMessage( harmSubMixVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* EXPANDER */

int	sndEffectExpand()
{
	MMI_SendMessage( expDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( expDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( expDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( expDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTEXP:expOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	expOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head ;

	int	var, min, max, delta, ptColumn ;
	int f, t, mul, c ;
	int ret ;

	setMsgColor( expMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;
	f = ( head->freq ) * 1000 / 0x62 ;				/* freq */
	f = ( f + 50 )/100 * 100 ;				/* 10の位を四捨五入 */

	MMI_SendMessage( expCycleNumId, MM_GETNUMBOX, 5,	/* 分割周期 */
						&var, &min, &max, &delta, &ptColumn ) ;
	t = f * var / 1000 ;

	MMI_SendMessage( expMulNumId, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul = var * 65536 / 100 ;

	MMI_SendMessage( expCrossNumId, MM_GETNUMBOX, 5,	/* cross over */
						&var, &min, &max, &delta, &ptColumn ) ;
	c = t * var / 100 ;

	ret = sndVoiceExpand( mul, t, c ) ;
	if( ret )
		errorCheck( ret ) ;

	setMsgColor( expMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTEXP:expPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	expPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( expMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( expMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTEXP:expUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	expUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( expMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( expMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTEXP:expInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	expInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( expDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( expDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTEXP:expCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	expCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTEXP:expMulVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTEXP:expMulNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	expMulSet(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 == expMulVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( expMulNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( expMulNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( expMulNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == expMulNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( expMulVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( expMulVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( expMulVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* LEVEL */

int	sndEffectLevel()
{
	MMI_SendMessage( levelDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( levelDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( levelDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( levelDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTLEV:levelOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	levelOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, delta, ptColumn ;
	int mul ;
	int ret ;

	setMsgColor( levelMesId[0], EXE_COLOR ) ;

	MMI_SendMessage( levelMulNumId, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul = pow( 10.0, ( (double)var / 200 ) ) * 65536 ;

	sndLevelExpand( mul ) ;

	ret = setMsgColor( levelMesId[0], MOJI_COLOR ) ;
	if( ret )
		errorCheck( ret ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTLEV:levelPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	levelPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( levelMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( levelMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTLEV:levelUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	levelUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( levelMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( levelMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTLEV:levelInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	levelInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( levelDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( levelDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTLEV:levelCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	levelCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTLEV:levelMulVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTLEV:levelMulNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	levelMulSet(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 == levelMulVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( levelMulNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( levelMulNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( levelMulNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == levelMulNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( levelMulVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( levelMulVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( levelMulVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* PITCH */

int	sndEffectPitch()
{
	MMI_SendMessage( pitchDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( pitchDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( pitchDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( pitchDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTPCH:pitchOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	pitchOkchk(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 mul, len ;

	setMsgColor( pitchMesId[0], EXE_COLOR ) ;

	head = (SNDHEAD *)sndBuf2 ;

	MMI_SendMessage( pitchMulNumId, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul = pow( 2.0, ( (double)var ) /1200 ) * 65536 ;

	len = head->length ;
	len = (double)len * 0x10000 / mul ;
	if( len > sndBufSize-32 )
	{
		errorCheck( OUT_OF_MEMORY ) ;
	}
	else
	{
		DWORD( para + 0 ) = (unsigned int)mul ;
		DWORD( para + 4 ) = (unsigned int)sndBufSize ;
		sndPitch( sndBuf2, sndBuf1, para, work ) ;
	}

	setMsgColor( pitchMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTPCH:pitchPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	pitchPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( pitchMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( pitchMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTPCH:pitchUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	pitchUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( pitchMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( pitchMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTPCH:pitchInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	pitchInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( pitchDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( pitchDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}

/*	initDataIOTPCH:pitchCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	pitchCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTPCH:pitchMulVolumeId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTPCH:pitchMulNumId:MJ_NUMBOXL40の呼び出し関数	*/
int	pitchMulSet(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 ;	/* 数値設定の変数 */

	/* volumeの方は実際の値の1/10 */

	if( kobj == pitchMulVolumeId )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( pitchMulNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( pitchMulNumId, MM_SETNUMBOX, 5,
							var*10, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( pitchMulNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == pitchMulNumId )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( pitchMulVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( pitchMulVolumeId, MM_SETSCROLL, 5,
										var2/10, min, max, len, page ) ;
		MMI_SendMessage( pitchMulVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}


/* SAMPLING RATE SET */

int	sndEffectSampSet()
{
	MMI_SendMessage( sampDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( sampDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( sampDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( sampDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/*	initDataIOTSMP:sampOkBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	sampOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	SNDHEAD *head1, *head2 ;
	char para[64] ;
	char work[512] ;
	int	var, min, max, delta, ptColumn ;
	int f, mul, len ;

	setMsgColor( sampMesId[0], EXE_COLOR ) ;

	head1 = (SNDHEAD *)sndBuf1 ;
	head2 = (SNDHEAD *)sndBuf2 ;

	MMI_SendMessage( sampRateNumId, MM_GETNUMBOX, 5,	/* freq */
						&var, &min, &max, &delta, &ptColumn ) ;
	f = var * 0x62 / 1000 ;
	mul = 65536 * ( head2->freq ) / f ;

	len = head2->length ;
	len = (double)len * 0x10000 / mul ;
	if( len > sndBufSize-32 )
	{
		errorCheck( OUT_OF_MEMORY ) ;
	}
	else
	{
		DWORD( para + 0 ) = (unsigned int)mul ;
		DWORD( para + 4 ) = (unsigned int)sndBufSize ;
		sndPitch( sndBuf2, sndBuf1, para, work ) ;
		head1->freq = f ;
	}

	setMsgColor( sampMesId[0], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTSMP:sampPlayBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	sampPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( sampMesId[1], EXE_COLOR ) ;

	sndPlay() ;

	setMsgColor( sampMesId[1], MOJI_COLOR ) ;

	return NOERR ;
}

/*	initDataIOTSMP:sampUndoBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	sampUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( sampMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( sampMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/*	initDataIOTSMP:sampCanBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	sampCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/*	initDataIOTSMP:sampInfBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	sampInf(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* ダイアログを使えないようにする */
	MTL_setAtrObj( sampDialogId, MS_DSPONLYL40 ) ;

	sndInf() ;

	/* ダイアログを使えるように戻す */
	MTL_resetAtrObj( sampDialogId, (~MS_DSPONLYL40) ) ;

	return NOERR ;
}


/* これ以後は, このソースのＣによる音声処理ルーチン */

static int sndLength ;

/*
ボイスチェンジャ
<<<引数の説明>>>
変換周波数の倍率, 1まとまりの出力データバイト数, クロスオーバ領域バイト数
*/
/* rateや率は65536倍の値 */
sndVoiceChng( mul, pack, dec )
int mul ;
int pack ;
int dec ;
{
	SNDHEAD *head ;
	int i, n, p ;
	int x, p0i, p0f, p1i, p1f ;

	if( pack <= 0 )
		pack = 1 ;

	head = (SNDHEAD *)sndBuf1 ;
	sndLength = head->length ;

	if( sndLength > sndBufSize-32 )
		return OUT_OF_MEMORY ;

	n = 0 ;
	p0i = n ;
	p0f = 0 ;
	p1i = n ;
	p1f = 0 ;

	while( n < sndLength )
	{
		p = 0 ;
		for( i=0 ; i<dec ; i++ )
		{
/*
			double keisuu ;
			keisuu = (cos( _PI*i/dec ) + 1 )/2 ;
			x = smpSnd( p0i, p0f ) * keisuu
			 + smpSnd( p1i, p1f ) * ( 1 - keisuu ) ;
*/
			int k ;
			k = ( hiSpeedSin( i*0x20000/dec + 0x10000 ) + 0x10000 ) >> 1 ;
			x = (smpSnd( p0i, p0f )* k
			 + smpSnd( p1i, p1f ) * ( 0x10000 - k )) >> 16 ;

			writeSnd( n, x ) ;
			addPoint( &p0i, &p0f, mul ) ;
			addPoint( &p1i, &p1f, mul ) ;
			p++ ;
			n++ ;
			if( n >= sndLength )goto voic01 ;
		}
		while( p < pack )
		{
			writeSnd( n, smpSnd( p1i, p1f ) ) ;
			addPoint( &p1i, &p1f, mul ) ;
			p++ ;
			n++ ;
			if( n >= sndLength )goto voic01 ;
		}
		p0i = p1i ;
		p0f = p1f ;
		p1i = n ;
		p1f = 0 ;
voic01:	;
	}

	return NOERR ;
}

/*
エキスパンダ
<<<引数の説明>>>
時間の倍率, 1まとまりの出力データバイト数, クロスオーバ領域バイト数
*/
/* rateや率は65536倍の値 */
sndVoiceExpand( mul, pack, dec )
int mul ;
int pack ;
int dec ;
{
	SNDHEAD *head1, *head2 ;
	int i, n, p ;
	int x, p0, p1 ;
	unsigned int newLength ;
	unsigned int loopp, loopl ;

	if( pack <= 0 )
		pack = 1 ;

	head1 = (SNDHEAD *)sndBuf1 ;
	head2 = (SNDHEAD *)sndBuf2 ;
	sndLength = head2->length ;
	newLength = ( (double)mul ) * sndLength / 0x10000 ;

	if( newLength > sndBufSize-32 )
		return OUT_OF_MEMORY ;

	head1->length = newLength ;
	loopp = head2->looppoint ;
	loopl = head2->looplength ;
	loopp = ( (double)mul ) * loopp / 0x10000 ;
	loopl = ( (double)mul ) * loopl / 0x10000 ;
	if( loopp >= newLength )loopp = newLength - 1 ;
	if( loopp+loopl > newLength )loopl = newLength - loopp ;
	head1->looppoint = loopp ;
	head1->looplength = loopl ;

	n = 0 ;
	p0 = n ;
	p1 = n ;

	while( n < newLength )
	{
		p = 0 ;
		for( i=0 ; i<dec ; i++ )
		{
/*
			double keisuu 
			x = ( readSnd( p0 ) * ( dec - i ) + readSnd( p1 ) * i ) / dec ;
			keisuu = (cos( _PI*i/dec ) + 1 )/2 ;
			x = readSnd( p0 ) * keisuu
			 + readSnd( p1 ) * ( 1 - keisuu ) ;
*/

			int k ;
			k = ( hiSpeedSin( i*0x20000/dec + 0x10000 ) + 0x10000 ) >> 1 ;
			x = (readSnd( p0 ) * k + readSnd( p1 ) * ( 0x10000 - k )) >> 16 ;

			writeSnd( n, x ) ;
			p0++ ;
			p1++ ;
			p++ ;
			n++ ;
			if( n >= newLength )goto voic01 ;
		}
		while( p < pack )
		{
			writeSnd( n, readSnd( p1 ) ) ;
			p1++ ;
			p++ ;
			n++ ;
			if( n >= newLength )goto voic01 ;
		}
		p0 = p1 ;
		p1 = ( (double)sndLength ) * n / newLength ;
voic01:	;
	}

	return NOERR ;
}

/* レベルコントロール */
/* rateや率は65536倍の値 */
sndLevelExpand( mul )
int mul ;
{
	SNDHEAD *head ;
	int i ;

	head = (SNDHEAD *)sndBuf1 ;
	sndLength = head->length ;
	if( sndLength > sndBufSize-32 )
		return OUT_OF_MEMORY ;

	for( i=0 ; i<sndLength ; i++ )
	{
		writeSnd(  i,   ( ( ( readSnd( i ) >> 8 ) * mul ) >> 8 )    ) ;
	}

	return NOERR ;
}

static int readSnd( i )
int i ;
{
	int d ;

	if( i >= sndLength )
		return 0 ;

	d = sndBuf2[ i + 32 ] ;
	d &= 0xff ;
	if( d >= 128 )
		d = 128 - d ;

	return ( d << 8 ) ;
}

static int smpSnd( i, f )
int i ;
int f ;
{
	int d1, d2 ;

	if( i >= sndLength )
		return 0 ;

	d1 = sndBuf2[ i + 32 ] ;
	d1 &= 0xff ;
	if( d1 >= 128 )
		d1 = 128 - d1 ;
	d2 = sndBuf2[ i + 33 ] ;
	d2 &= 0xff ;
	if( d2 >= 128 )
		d2 = 128 - d2 ;
	f &= 0xffff ;

	return ( ( d1 * ( 0x10000 - f ) + d2 * f ) >> 8 ) ;
}

static int writeSnd( p, x )
int p ;
int x ;
{
	x = ( x >> 8 ) ;

	if( x <= 0 )
	{
		x = 128 - x ;
		if( x > 254 )
			x = 254 ;
	}
	else if( x > 127 )
		x = 127 ;

	sndBuf1[ p + 32 ] = x ;

	return NOERR ;
}

static int addPoint( i, f, mul )
int *i ;
int *f ;
int mul ;
{

	*f = *f + mul ;
	*i = *i + ( *f >> 16 ) ;
	*f = ( *f & 0xffff ) ;

	return NOERR ;
}

