#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 "wavhime.h"
#include "otolib.h"

/* voice change */
int	voicDialogId = -1 ;
int	voicOkBtnId = -1 ;
int	voicPlayBtnId = -1 ;
int	voicUndoBtnId = -1 ;
int	voicFixBtnId = -1 ;
int	voicCanBtnId = -1 ;
int	voicMesId[29] = -1 ;
int	voicSubDialogId = -1 ;
int	voicMulVolumeId = -1 ;
int	voicMulNumId = -1 ;
int	voicCycleNumId = -1 ;
int	voicCrossNumId = -1 ;
int	voicBtnId[3] = -1 ;
int	voicInfBtnId = -1 ;

/* harmony */
int	harmDialogId = -1 ;
int	harmOkBtnId = -1 ;
int	harmPlayBtnId = -1 ;
int	harmUndoBtnId = -1 ;
int	harmFixBtnId = -1 ;
int	harmCanBtnId = -1 ;
int	harmMesId[32] = -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 ;
int	harmBtnId[3] = -1 ;
int	harmInfBtnId = -1 ;

/* expander */
int	expDialogId = -1 ;
int	expOkBtnId = -1 ;
int	expPlayBtnId = -1 ;
int	expUndoBtnId = -1 ;
int	expFixBtnId = -1 ;
int	expCanBtnId = -1 ;
int	expMesId[24] = -1 ;
int	expSubDialogId = -1 ;
int	expMulVolumeId = -1 ;
int	expMulNumId = -1 ;
int	expCycleNumId = -1 ;
int	expCrossNumId = -1 ;
int	expInfBtnId = -1 ;

/* level */
int	levelDialogId = -1 ;
int	levelOkBtnId = -1 ;
int	levelPlayBtnId = -1 ;
int	levelUndoBtnId = -1 ;
int	levelFixBtnId = -1 ;
int	levelCanBtnId = -1 ;
int	levelMesId[34] = -1 ;
int	levelSubDialogId = -1 ;
int	levelMulVolumeIdL = -1 ;
int	levelMulNumIdL = -1 ;
int	levelMulVolumeIdR = -1 ;
int	levelMulNumIdR = -1 ;
int	levelInfBtnId = -1 ;

/* pitch */
int	pitchDialogId = -1 ;
int	pitchOkBtnId = -1 ;
int	pitchPlayBtnId = -1 ;
int	pitchUndoBtnId = -1 ;
int	pitchFixBtnId = -1 ;
int	pitchCanBtnId = -1 ;
int	pitchMesId[21] = -1 ;
int	pitchSubDialogId = -1 ;
int	pitchMulVolumeId = -1 ;
int	pitchMulNumId = -1 ;
int	pitchInfBtnId = -1 ;

/* sampling rate set */
int	sampDialogId = -1 ;
int	sampOkBtnId = -1 ;
int	sampPlayBtnId = -1 ;
int	sampUndoBtnId = -1 ;
int	sampCanBtnId = -1 ;
int	sampMesId[17] = -1 ;
int	sampSubDialogId = -1 ;
int	sampRateBtnId[3] = -1 ;
int	sampBitBtnId[2] = -1 ;
int	sampChanBtnId[2] = -1 ;
int	sampFixBtnId = -1 ;
int	sampInfBtnId = -1 ;


/* VOICE CHANGE */

static int voicMode = 0 ;

int	sndEffectVoiceChange()
{
	MMI_SendMessage( voicDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;

	MTL_setFlagObj( voicBtnId[voicMode], (MS_UNSELECT | MS_TOGGLE) ) ;

	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 ;
{
	int	var, min, max, delta, ptColumn ;
	int f, t, mul, c ;
	int ret ;
	int bit, kd, sz ;

	SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
	setMsgColor( voicMesId[0], EXE_COLOR ) ;

	if( tempFileCount == 0 )	/* テンポラリファイルの数が0なら */
	{
		ret = NO_DATA ;
		goto END_00 ;
	}
	else if( tempFileCount == 1 )	/* テンポラリファイルの数が1なら */
	{
		if( (ret = temp1_to_temp2()) != NOERR )		/* temp1をtemp2へ */
			goto END_00 ;
	}

	if( (ret = readWavDataInfo( &f, &bit, &kd, &sz )) != NOERR )
		goto END_00 ;

	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, voicMode ) ;

END_00: ;
	setMsgColor( voicMesId[0], MOJI_COLOR ) ;
	SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

	if( ret )
		errorCheck( ret ) ;

	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:voicFixBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	voicFix(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	delTemp2() ;
	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:voicBtnId[0]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIOTVOI:voicBtnId[1]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIOTVOI:voicBtnId[2]:MJ_TICONL40の呼び出し関数	*/
int	voicModeSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int i ;

	for( i=0 ; i<3 ; i++ )
	{
		if( kobj == voicBtnId[i] )
		{
			MTL_setFlagObj( voicBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( voicBtnId[voicMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( voicBtnId[voicMode], MM_SHOW, 0 ) ;
			voicMode = i ;
		}
	}
	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 */

static int harmMode = 0 ;

int	sndEffectHarmony()
{
	MMI_SendMessage( harmDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;

	MTL_setFlagObj( harmBtnId[harmMode], (MS_UNSELECT | MS_TOGGLE) ) ;

	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 ;
{
	int	var, min, max, delta, ptColumn ;
	int f, t, mul, c, mix1, mix2 ;
	int ret ;
	int bit, kd, sz ;

	SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
	setMsgColor( harmMesId[0], EXE_COLOR ) ;

	if( tempFileCount == 0 )	/* テンポラリファイルの数が0なら */
	{
		ret = NO_DATA ;
		goto END_00 ;
	}
	else if( tempFileCount == 1 )	/* テンポラリファイルの数が1なら */
	{
		if( (ret = temp1_to_temp2()) != NOERR )		/* temp1をtemp2へ */
			goto END_00 ;
	}

	if( (ret = readWavDataInfo( &f, &bit, &kd, &sz )) != NOERR )
		goto END_00 ;

	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 ;

	MMI_SendMessage( harmMainMixNumId, MM_GETNUMBOX, 5,
					&var, &min, &max, &delta, &ptColumn ) ;
	mix1 = var * 256 / 100 ;
	MMI_SendMessage( harmSubMixNumId, MM_GETNUMBOX, 5,
					&var, &min, &max, &delta, &ptColumn ) ;
	mix2 = var * 256 / 100 ;

	ret = sndHarmony( mul, t, c, mix1, mix2, harmMode ) ;

END_00: ;
	setMsgColor( harmMesId[0], MOJI_COLOR ) ;
	SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

	if( ret )
		errorCheck( ret ) ;

	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:harmFixBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	harmFix(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	delTemp2() ;
	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:harmBtnId[0]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIOTHAR:harmBtnId[1]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIOTHAR:harmBtnId[2]:MJ_TICONL40の呼び出し関数	*/
int	harmModeSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int i ;

	for( i=0 ; i<3 ; i++ )
	{
		if( kobj == harmBtnId[i] )
		{
			MTL_setFlagObj( harmBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( harmBtnId[harmMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( harmBtnId[harmMode], MM_SHOW, 0 ) ;
			harmMode = i ;
		}
	}
	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 ;
{
	int	var, min, max, delta, ptColumn ;
	int f, t, mul, c ;
	int ret ;
	int bit, kd, sz ;

	SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
	setMsgColor( expMesId[0], EXE_COLOR ) ;

	if( tempFileCount == 0 )	/* テンポラリファイルの数が0なら */
	{
		ret = NO_DATA ;
		goto END_00 ;
	}
	else if( tempFileCount == 1 )	/* テンポラリファイルの数が1なら */
	{
		if( (ret = temp1_to_temp2()) != NOERR )		/* temp1をtemp2へ */
			goto END_00 ;
	}

	if( (ret = readWavDataInfo( &f, &bit, &kd, &sz )) != NOERR )
		goto END_00 ;

	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 ) ;

END_00: ;
	setMsgColor( expMesId[0], MOJI_COLOR ) ;
	SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

	if( ret )
		errorCheck( ret ) ;

	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:expFixBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	expFix(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	delTemp2() ;
	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 mul1, mul2 ;
	int ret ;

	SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
	setMsgColor( levelMesId[0], EXE_COLOR ) ;

	if( tempFileCount == 0 )	/* テンポラリファイルの数が0なら */
	{
		ret = NO_DATA ;
		goto END_00 ;
	}
	else if( tempFileCount == 1 )	/* テンポラリファイルの数が1なら */
	{
		if( (ret = temp1_to_temp2()) != NOERR )		/* temp1をtemp2へ */
			goto END_00 ;
	}

	MMI_SendMessage( levelMulNumIdL, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul1 = pow( 10.0, ( (double)var / 200 ) ) * 256 ;

	MMI_SendMessage( levelMulNumIdR, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul2 = pow( 10.0, ( (double)var / 200 ) ) * 256 ;

	ret = sndLevelExpand( mul1, mul2 ) ;

END_00: ;
	setMsgColor( levelMesId[0], MOJI_COLOR ) ;
	SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

	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:levelFixBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	levelFix(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	delTemp2() ;
	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:levelMulVolumeIdL:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTLEV:levelMulNumIdL:MJ_NUMBOXL40の呼び出し関数	*/
int	levelMulSetL(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 == levelMulVolumeIdL )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( levelMulNumIdL, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( levelMulNumIdL, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( levelMulNumIdL, MM_SHOW, 0 ) ;
	}

	if( kobj == levelMulNumIdL )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( levelMulVolumeIdL, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( levelMulVolumeIdL, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( levelMulVolumeIdL, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/*	initDataIOTLEV:levelMulVolumeIdR:MJ_SCRLL40の呼び出し関数	*/
/*	initDataIOTLEV:levelMulNumIdR:MJ_NUMBOXL40の呼び出し関数	*/
int	levelMulSetR(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 == levelMulVolumeIdR )
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( levelMulNumIdR, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( levelMulNumIdR, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( levelMulNumIdR, MM_SHOW, 0 ) ;
	}

	if( kobj == levelMulNumIdR )
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( levelMulVolumeIdR, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( levelMulVolumeIdR, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( levelMulVolumeIdR, 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 ;
{
	int	var, min, max, delta, ptColumn ;
	int mul ;
	int ret ;

	SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
	setMsgColor( pitchMesId[0], EXE_COLOR ) ;

	if( tempFileCount == 0 )	/* テンポラリファイルの数が0なら */
	{
		ret = NO_DATA ;
		goto END_00 ;
	}
	else if( tempFileCount == 1 )	/* テンポラリファイルの数が1なら */
	{
		if( (ret = temp1_to_temp2()) != NOERR )		/* temp1をtemp2へ */
			goto END_00 ;
	}

	MMI_SendMessage( pitchMulNumId, MM_GETNUMBOX, 5,	/* Mul */
						&var, &min, &max, &delta, &ptColumn ) ;
	mul = pow( 2.0, ( (double)var ) /1200 ) * 65536 ;

	ret = sndPitchControl( mul ) ;

END_00: ;
	setMsgColor( pitchMesId[0], MOJI_COLOR ) ;
	SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

	if( ret )
		errorCheck( ret ) ;

	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:pitchFixBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	pitchFix(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	delTemp2() ;
	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 */

static int sampRateMode = 0 ;
static int sampBitMode = 0 ;
static int sampChanMode = 0 ;

int	sndEffectSampSet()
{
	MMI_SendMessage( sampDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;

	MTL_setFlagObj( sampRateBtnId[sampRateMode], (MS_UNSELECT | MS_TOGGLE) ) ;
	MTL_setFlagObj( sampBitBtnId[sampBitMode], (MS_UNSELECT | MS_TOGGLE) ) ;
	MTL_setFlagObj( sampChanBtnId[sampChanMode], (MS_UNSELECT | MS_TOGGLE) ) ;

	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 ;
{
	int ret ;
	int fq, bit, kd ;

	SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
	setMsgColor( sampMesId[0], EXE_COLOR ) ;

	if( tempFileCount == 0 )	/* テンポラリファイルの数が0なら */
	{
		ret = NO_DATA ;
		goto END_00 ;
	}
	else if( tempFileCount == 1 )	/* テンポラリファイルの数が1なら */
	{
		if( (ret = temp1_to_temp2()) != NOERR )		/* temp1をtemp2へ */
			goto END_00 ;
	}

	switch( sampRateMode )
	{
	case 0:
		fq = 44100 ;
		break ;
	case 1:
		fq = 22050 ;
		break ;
	case 2:
		fq = 11025 ;
		break ;
	}

	switch( sampBitMode )
	{
	case 0:
		bit = 16 ;
		break ;
	case 1:
		bit = 8 ;
		break ;
	}

	switch( sampChanMode )
	{
	case 0:
		kd = 2 ;
		break ;
	case 1:
		kd = 1 ;
		break ;
	}

	ret = sampRateChange( fq, bit, kd ) ;

END_00: ;
	setMsgColor( sampMesId[0], MOJI_COLOR ) ;
	SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

	if( ret )
		errorCheck( ret ) ;

	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 ;
}

/*	initDataIWVSMP:sampFixBtnId:MJ_DBUTTONL40の呼び出し関数	*/
int	sampFix(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	delTemp2() ;
	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 ;
}

/*	initDataIWVSMP:sampRateBtnId[0〜2]:MJ_TICONL40の呼び出し関数	*/
int	sampRateSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int i ;

	for( i=0 ; i<3 ; i++ )
	{
		if( kobj == sampRateBtnId[i] )
		{
			MTL_setFlagObj( sampRateBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( sampRateBtnId[sampRateMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( sampRateBtnId[sampRateMode], MM_SHOW, 0 ) ;
			sampRateMode = i ;
		}
	}
	return NOERR ;
}

/*	initDataIWVSMP:sampBitBtnId[0〜1]:MJ_TICONL40の呼び出し関数	*/
int	sampBitSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int i ;

	for( i=0 ; i<2 ; i++ )
	{
		if( kobj == sampBitBtnId[i] )
		{
			MTL_setFlagObj( sampBitBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( sampBitBtnId[sampBitMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( sampBitBtnId[sampBitMode], MM_SHOW, 0 ) ;
			sampBitMode = i ;
		}
	}
	return NOERR ;
}

/*	initDataIWVSMP:sampChanBtnId[0〜1]:MJ_TICONL40の呼び出し関数	*/
int	sampChanSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int i ;

	for( i=0 ; i<2 ; i++ )
	{
		if( kobj == sampChanBtnId[i] )
		{
			MTL_setFlagObj( sampChanBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( sampChanBtnId[sampChanMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( sampChanBtnId[sampChanMode], MM_SHOW, 0 ) ;
			sampChanMode = i ;
		}
	}
	return NOERR ;
}

/* これ以後は, このソースのＣによる音声処理ルーチン */

/*
ボイスチェンジャ
<<<引数の説明>>>
変換周波数の倍率, 1まとまりの出力データ数, クロスオーバ領域バイト数
mode 0:stero 1:left 2:right
*/
/* rateや率は65536倍の値 */
sndVoiceChng( mul, pack, dec, mode )
int mul ;
int pack ;
int dec ;
int mode ;
{
	int i, n, p ;
	int p0i, p0f, p1i, p1f ;
	int fq, bit, kd, sz ;
	int x1, x2, y1, y2, ret ;
	int sndLength ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}
	if( kd == 1 )			// モノラルの時
		mode = 0 ;

	if( pack <= 0 )
		pack = 1 ;

	sndLength = sz / ( kd * bit/8 ) ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	n = 0 ;
	p0i = n ;
	p0f = 0 ;
	p1i = n ;
	p1f = 0 ;

	while( n < sndLength )
	{
		p = 0 ;
		for( i=0 ; i<dec ; i++ )
		{
			int k ;
//			k = (cos( _PI*i/dec ) + 1 )/2 * 0x10000 ;
			k = ( hiSpeedSin( i*0x20000/dec + 0x10000 ) + 0x10000 ) >> 1 ;

			switch( mode )
			{
			case 0:
					if( (ret = smpSnd( p0i, p0f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = smpSnd( p1i, p1f, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = (x1 * k + y1 * ( 0x10000 - k )) >> 16 ;
					x2 = (x2 * k + y2 * ( 0x10000 - k )) >> 16 ;
					if( (ret = writeWavData( x1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 1:	
					if( (ret = smpSnd( p0i, p0f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = smpSnd( p1i, p1f, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = (x1 * k + y1 * ( 0x10000 - k )) >> 16 ;
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = writeWavData( x1, y2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 2:	
					if( (ret = smpSnd( p0i, p0f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = smpSnd( p1i, p1f, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x2 = (x2 * k + y2 * ( 0x10000 - k )) >> 16 ;
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = writeWavData( y1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			}
			addPoint( &p0i, &p0f, mul ) ;
			addPoint( &p1i, &p1f, mul ) ;
			p++ ;
			n++ ;
			if( n >= sndLength )goto voic01 ;
		}
		while( p < pack )
		{
			switch( mode )
			{
			case 0:
					if( (ret = smpSnd( p1i, p1f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = writeWavData( x1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 1:	
					if( (ret = smpSnd( p1i, p1f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = writeWavData( x1, y2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 2:	
					if( (ret = smpSnd( p1i, p1f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = writeWavData( y1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			}
			addPoint( &p1i, &p1f, mul ) ;
			p++ ;
			n++ ;
			if( n >= sndLength )goto voic01 ;
		}
		p0i = p1i ;
		p0f = p1f ;
		p1i = n ;
		p1f = 0 ;
voic01:	;
	}
	writeWavData_end() ;
	readWavData_end() ;

	return NOERR ;
}

/*
ハーモニー
<<<引数の説明>>>
変換周波数の倍率, 1まとまりの出力データ数, クロスオーバ領域バイト数
mix1 org mix rate, mix2 harmony mix rate
mode 0:stero 1:left 2:right
*/
/* rateや率は65536倍の値 */
sndHarmony( mul, pack, dec, mix1, mix2, mode )
int mul ;
int pack ;
int dec ;
int mix1 ;
int mix2 ;
int mode ;
{
	int i, n, p ;
	int p0i, p0f, p1i, p1f ;
	int fq, bit, kd, sz ;
	int x1, x2, y1, y2, ret ;
	int sndLength ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}
	if( kd == 1 )			// モノラルの時
		mode = 0 ;

	if( pack <= 0 )
		pack = 1 ;

	sndLength = sz / ( kd * bit/8 ) ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	n = 0 ;
	p0i = n ;
	p0f = 0 ;
	p1i = n ;
	p1f = 0 ;

	while( n < sndLength )
	{
		p = 0 ;
		for( i=0 ; i<dec ; i++ )
		{
			int k ;
//			k = (cos( _PI*i/dec ) + 1 )/2 * 0x10000 ;
			k = ( hiSpeedSin( i*0x20000/dec + 0x10000 ) + 0x10000 ) >> 1 ;

			switch( mode )
			{
			case 0:
					if( (ret = smpSnd( p0i, p0f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = smpSnd( p1i, p1f, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = (x1 * k + y1 * ( 0x10000 - k )) >> 16 ;
					x2 = (x2 * k + y2 * ( 0x10000 - k )) >> 16 ;
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = ( x1 * mix2 + y1 * mix1 ) >> 8 ;
					x2 = ( x2 * mix2 + y2 * mix1 ) >> 8 ;
					if( (ret = writeWavData( x1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 1:	
					if( (ret = smpSnd( p0i, p0f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = smpSnd( p1i, p1f, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = (x1 * k + y1 * ( 0x10000 - k )) >> 16 ;
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = ( x1 * mix2 + y1 * mix1 ) >> 8 ;
					if( (ret = writeWavData( x1, y2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 2:	
					if( (ret = smpSnd( p0i, p0f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = smpSnd( p1i, p1f, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x2 = (x2 * k + y2 * ( 0x10000 - k )) >> 16 ;
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x2 = ( x2 * mix2 + y2 * mix1 ) >> 8 ;
					if( (ret = writeWavData( y1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			}
			addPoint( &p0i, &p0f, mul ) ;
			addPoint( &p1i, &p1f, mul ) ;
			p++ ;
			n++ ;
			if( n >= sndLength )goto voic01 ;
		}
		while( p < pack )
		{
			switch( mode )
			{
			case 0:
					if( (ret = smpSnd( p1i, p1f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = ( x1 * mix2 + y1 * mix1 ) >> 8 ;
					x2 = ( x2 * mix2 + y2 * mix1 ) >> 8 ;
					if( (ret = writeWavData( x1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 1:	
					if( (ret = smpSnd( p1i, p1f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x1 = ( x1 * mix2 + y1 * mix1 ) >> 8 ;
					if( (ret = writeWavData( x1, y2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			case 2:	
					if( (ret = smpSnd( p1i, p1f, &x1, &x2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					if( (ret = readWavData( n, &y1, &y2 )) != NOERR )
					{
						writeWavData_end() ;
						return ret ;
					}
					x2 = ( x2 * mix2 + y2 * mix1 ) >> 8 ;
					if( (ret = writeWavData( y1, x2 )) != NOERR )
					{
						readWavData_end() ;
						return ret ;
					}
					break ;
			}
			addPoint( &p1i, &p1f, mul ) ;
			p++ ;
			n++ ;
			if( n >= sndLength )goto voic01 ;
		}
		p0i = p1i ;
		p0f = p1f ;
		p1i = n ;
		p1f = 0 ;
voic01:	;
	}
	writeWavData_end() ;
	readWavData_end() ;

	return NOERR ;
}

/*
エキスパンダ
<<<引数の説明>>>
時間の倍率, 1まとまりの出力データバイト数, クロスオーバ領域バイト数
*/
/* rateや率は65536倍の値 */
sndVoiceExpand( mul, pack, dec )
int mul ;
int pack ;
int dec ;
{
	int i, n, p ;
	int p0, p1 ;
	unsigned int newLength ;
	int x1, x2, y1, y2, ret ;
	int fq, bit, kd, sz ;
	int sndLength ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}

	if( pack <= 0 )
		pack = 1 ;
	sndLength = sz / ( kd * bit/8 ) ;
	newLength = ( (double)mul ) * sndLength / 0x10000 ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	n = 0 ;
	p0 = n ;
	p1 = n ;

	while( n < newLength )
	{
		p = 0 ;
		for( i=0 ; i<dec ; i++ )
		{
			int k ;
//			k = (cos( _PI*i/dec ) + 1 )/2 * 0x10000 ;
			k = ( hiSpeedSin( i*0x20000/dec + 0x10000 ) + 0x10000 ) >> 1 ;

			if( (ret = readWavData( p0, &x1, &x2 )) != NOERR )
			{
				writeWavData_end() ;
				return ret ;
			}
			if( (ret = readWavData( p1, &y1, &y2 )) != NOERR )
			{
				writeWavData_end() ;
				return ret ;
			}
			x1 = (x1 * k + y1 * ( 0x10000 - k )) >> 16 ;
			x2 = (x2 * k + y2 * ( 0x10000 - k )) >> 16 ;
			if( (ret = writeWavData( x1, x2 )) != NOERR )
			{
				readWavData_end() ;
				return ret ;
			}
			p0++ ;
			p1++ ;
			p++ ;
			n++ ;
			if( n >= newLength )goto voic01 ;
		}
		while( p < pack )
		{
			if( (ret = readWavData( p1, &x1, &x2 )) != NOERR )
			{
				writeWavData_end() ;
				return ret ;
			}
			if( (ret = writeWavData( x1, x2 )) != NOERR )
			{
				readWavData_end() ;
				return ret ;
			}
			p1++ ;
			p++ ;
			n++ ;
			if( n >= newLength )goto voic01 ;
		}
		p0 = p1 ;
		p1 = ( (double)sndLength ) * n / newLength ;
voic01:	;
	}
	writeWavData_end() ;
	readWavData_end() ;

	return NOERR ;
}

/* レベルコントロール */
/* rateや率は256倍の値 */
sndLevelExpand( mul1, mul2 )
int mul1 ;
int mul2 ;
{
	int i ;
	int x1, x2, ret ;
	int fq, bit, kd, sz ;
	int sndLength ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}

	sndLength = sz / ( kd * bit/8 ) ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	for( i=0 ; i<sndLength ; i++ )
	{
		if( (ret = readWavData( i, &x1, &x2 )) != NOERR )
		{
			writeWavData_end() ;
			return ret ;
		}
		x1 = ( x1 * mul1 ) >> 8 ;
		x2 = ( x2 * mul2 ) >> 8 ;
		if( (ret = writeWavData( x1, x2 )) != NOERR )
		{
			readWavData_end() ;
			return ret ;
		}
	}
	writeWavData_end() ;
	readWavData_end() ;

	return NOERR ;
}

/*
ピッチコントロール
<<<引数の説明>>>
倍率
*/
/* rateや率は65536倍の値 */
sndPitchControl( mul )
int mul ;
{
	int i ;
	int pi, pf ;
	unsigned int newLength ;
	int x1, x2, ret ;
	int fq, bit, kd, sz ;
	int sndLength ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}

	sndLength = sz / ( kd * bit/8 ) ;
	newLength = ( (double)sndLength ) * 0x10000 / mul ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	pi = 0 ;
	pf = 0 ;

	for( i=0 ; i<newLength ; i++ )
	{
		if( (ret = smpSnd( pi, pf, &x1, &x2 )) != NOERR )
		{
			writeWavData_end() ;
			return ret ;
		}
		if( (ret = writeWavData( x1, x2 )) != NOERR )
		{
			readWavData_end() ;
			return ret ;
		}
		addPoint( &pi, &pf, mul ) ;

		if( pi >= sndLength )
			break ;
	}
	writeWavData_end() ;
	readWavData_end() ;

	return NOERR ;
}

static int smpSnd( i, f, left, right )
int i ;
int f ;
int *left ;
int *right ;
{
	int x1, x2, y1, y2, ret ;

	if( (ret = readWavData( i, &x1, &x2 )) != NOERR )
		return ret ;
	if( (ret = readWavData( i+1, &y1, &y2 )) != NOERR )
		return ret ;

	f &= 0xffff ;
	*left = ( x1 * ( 0x10000 - f ) + y1 * f ) >> 16 ;
	*right = ( x2 * ( 0x10000 - f ) + y2 * f ) >> 16 ;

	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 ;
}

int sampRateChange( int freq, int bitno, int kind )
{
	int i ;
	int pi, pf ;
	unsigned int newLength ;
	int x1, x2, ret, mul ;
	int fq, bit, kd, sz ;
	int sndLength ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}

	mul = ( (double)fq ) * 0x10000 / freq ;

	sndLength = sz / ( kd * bit/8 ) ;
	newLength = ( (double)sndLength ) * freq / fq ;

	if( (ret = writeWavData_init( freq, bitno, kind, sz )) != NOERR )
	{												// szは何の値でもいい
		readWavData_end() ;
		return ret ;
	}

	pi = 0 ;
	pf = 0 ;

	for( i=0 ; i<newLength ; i++ )
	{
		if( (ret = smpSnd( pi, pf, &x1, &x2 )) != NOERR )
		{
			writeWavData_end() ;
			return ret ;
		}

		if( (kd == 1) && (kind == 2) )		// モノ→ステレオ
		{
			x2 = x1 ;
		}
		else if( (kd == 2) && (kind == 1) )		// ステレオ→モノ
		{
			x1 = ( x1 + x2 ) >> 1 ;
			x2 = x1 ;
		}

		if( (ret = writeWavData( x1, x2 )) != NOERR )
		{
			readWavData_end() ;
			return ret ;
		}
		addPoint( &pi, &pf, mul ) ;

		if( pi >= sndLength )
			break ;
	}
	writeWavData_end() ;
	readWavData_end() ;

	return NOERR ;
}

