/* 音姫 main sub 1993 12/26 */

#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"

/* about */
int	alertId = -1 ;
int	messageId[3] = -1 ;
int	dspIconId = -1 ;
int	aboutOKBtnId = -1 ;

/* information */
int	infDialogId = -1 ;
int	infMsgId[8] = -1 ;
int	infNumId[6] = -1 ;
int	infOkBtnId = -1 ;

/* desk */
int	baseDialogId = -1 ;
int	menubarId = -1 ;
int	menuId = -1 ;
int	mItemId[3] = -1 ;
int	SDKmenuId = -1 ;
int	SDKmItemId[3] = -1 ;
int	fileMenuId = -1 ;
int	fileMItemId[8] = -1 ;
int	effMenuId = -1 ;
int	effMItemId[14] = -1 ;
int	quitIconId = -1 ;
int	errorId = -1 ;
int	errorOKBtnId = -1 ;
int	errorIconId = -1 ;
int	errormessage[2] = -1 ;

int	sndBufSize ;
char * sndBuf1 ;
char * sndBuf2 ;

	/* 各コマンド呼び出し */

char sndFileName[100] ;

/* ファイル */

/* load */
int	selectFunc0(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	char path[100] ;
	char *ExtStr[] = { "*.SND", NULL } ;
	int i,ret ;

	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	ret = fileSelecter( sndFileName, ExtStr,
							"読  込", "実  行", "取  消");

	if( ret == NOERR )
	{
		/* name , kakuchou[拡張子(.***)] → fullname = name + kakuchou */
		file_kakuchousi_set( path, sndFileName, ".SND" ) ;
		for( i=0 ; i<100 ; i++ )
			sndFileName[i] = path[i] ;

		ret = pcmSndRead( sndFileName ) ;
		if( ret )
			errorCheck( ret ) ;
	}

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* 重ね合わせ */
int	selectFunc1(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	char path[100] ;
	char *ExtStr[] = { "*.SND", NULL } ;
	int i,ret ;

	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	ret = fileSelecter( sndFileName, ExtStr,
							"重ね合わせ", "選  択", "取  消");

	if( ret == NOERR )
	{
		/* name , kakuchou[拡張子(.***)] → fullname = name + kakuchou */
		file_kakuchousi_set( path, sndFileName, ".SND" ) ;
		for( i=0 ; i<100 ; i++ )
			sndFileName[i] = path[i] ;

		ret = pcmSndRead( sndFileName ) ;
		if( ret )
			errorCheck( ret ) ;
		else
			sndMix() ;
	}

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

	/* SNDファイルを読み込む */
int pcmSndRead( char *name )
{
	FILE *fp ;	    /* ファイルのストリーム情報を記憶する変数のポインタ */
	int len ;		/* SNDデータのデータ幅 */
	SNDHEAD head ;	/* SNDデータのヘッダの内容が入る構造体変数 */

	if( ( fp = fopen( name, "rb" ) ) == NULL )	/* ファイルオープン */
	{
		return CANT_LOAD ;  	  /* オープンできなかったらエラーを返す */
	}

	if( fread( &head, 32, 1, fp ) < 1 )	/* ヘッダ読み込み */
	{
		fclose( fp ) ;	  		/* 読み込めない場合はまずクローズする */
		return CANT_LOAD ;		/* エラーを返す */
	}

	len = head.length ;			/* データ幅を取得 */

	if( len > (sndBufSize - 32) ) /* メモリのcheck */
	{
		fclose( fp ) ;  		/* メモリが足りない場合まずクローズする */
		return OUT_OF_MEMORY ;	/* エラーを返す */
	}

	fseek( fp, 0, SEEK_SET ); /* ファイルのストリームの位置を0に戻す */

	if( fread( sndBuf1, len+32, 1, fp ) < 1 )	  /* バッファに読み込み */
	{
		fclose( fp ) ;	  		/* クローズする */
		return CANT_LOAD ;		/* エラーを返す */
	}

	fclose( fp ) ;					/* クローズ */

	return NOERR ;
}

/* save */
int	selectFunc2(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	char path[100] ;
	char *ExtStr[] = { "*.SND", NULL } ;
	int i,ret ;

	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	ret = fileSelecter( sndFileName, ExtStr,
							"保  存", "実  行", "取  消");

	if( ret == NOERR )
	{
		/* name , kakuchou[拡張子(.***)] → fullname = name + kakuchou */
		file_kakuchousi_set( path, sndFileName, ".SND" ) ;
		for( i=0 ; i<100 ; i++ )
			sndFileName[i] = path[i] ;

		ret = pcmSndWrite( sndFileName ) ;
		if( ret )
			errorCheck( ret ) ;
	}

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

	/* SNDファイルを書き込む */
int pcmSndWrite( char *name )
{
	FILE *fp ;	    /* ファイルのストリーム情報を記憶する変数のポインタ */
	int len ;		/* SNDデータのデータ幅 */
	SNDHEAD *head ;	/* SNDデータのヘッダの内容が入る構造体変数 */

	if( ( fp = fopen( name, "wb" ) ) == NULL )	/* ファイルオープン */
	{
		return CANT_SAVE ;  	  /* オープンできなかったらエラーを返す */
	}

	head = (SNDHEAD *)sndBuf1 ;
	len = head->length ;			/* データ幅を取得 */

	if( len > (sndBufSize - 32) ) /* 大きさのcheck */
	{
		head->length = sndBufSize - 32 ;
		len = sndBufSize - 32 ;
	}

	if( fwrite( sndBuf1, len+32, 1, fp ) < 1 )	  /* 書き込み */
	{
		fclose( fp ) ;	  		/* クローズする */
		return CANT_SAVE ;		/* エラーを返す */
	}

	fclose( fp ) ;					/* クローズ */

	return NOERR ;
}

/* rec */
int	selectFunc3(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndRec() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* play */
int	selectFunc4(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	sndPlay() ;
	return NOERR ;
}


/* 効果 */

/* echo */
int	effFunc0(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectEcho() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* phase */
int	effFunc1(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectPhaseShift() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* vibrato */
int	effFunc2(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectVibrato() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* tremolo */
int	effFunc3(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectTremolo() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* voice changer */
int	effFunc4(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectVoiceChange() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* harmony */
int	effFunc4_2(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectHarmony() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* expander */
int	effFunc5(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectExpand() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* level */
int	effFunc6(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectLevel() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* pitch */
int	effFunc7(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectPitch() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* fade int & out */
int	effFunc8(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectFade() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* sampling rate */
int	effFunc9(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectSampSet() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* write head */
int	effFunc10(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndBufTrans() ;		/* サウンドデータ退避 */

	sndEffectHead() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* undo */
int	effFunc11(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	unDo() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}


/* 情報 */

int	information(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	sndInf() ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}



/*

		ここからは 汎用サブルーチン

*/

/* name , kakuchou[拡張子(.***)] → fullname = name + kakuchou */

file_kakuchousi_set( fullname, name, kakuchou )
char fullname[], name[], kakuchou[];
{
	int i;

	for( i=0 ; i<76 ; i++ ){
		fullname[i] = name[i];
		if( name[i] == '.' || name[i] == (char)0 )goto mov01;
	}
	return 55;		/* bad file name */
mov01:	if( i == 0 )return 55;
	if( name[i-1] == '\\' )return 55;
	DWORD( fullname + i ) = DWORD( kakuchou );
	fullname[i+4] = (char)0;
	return 0;
}

/*	ファイル選択	*/

int	fileSelecter( path, ExtStr, title, exec, cncl )
char	*path ;
char	**ExtStr ;
char	*title ;
char	*exec ;
char	*cncl ;
{
	char pathName[100], name[20] ;
	int				 i, j, n ;
	unsigned int	MSlctCnt ;
	int		  Atr, ret, ret2 ;

	ret2 = NOERR ;

	n = 0 ;
	for( i=0 ; i<79 ; i++ )
	{
		pathName[i] = path[i] ;
		if( path[i] == '\\' )
			n++ ;
		if( path[i] == '\0' )
			break ;
	}
	if( n <= 1 )
	{
		for( i=i ; i>=0 ; i-- )
		{
			if( path[i] == '\\' )
			{
				i++ ;
				pathName[i] = '\0' ;
				break ;
			}
		}
		for( j=0 ; j<13 ; j++ )
		{
			name[j] = path[i+j] ;
		}
	}
	else
	{
		for( i=i ; i>=0 ; i-- )
		{
			if( path[i] == '\\' )
			{
				pathName[i] = '\0' ;
				break ;
			}
		}
		for( j=0 ; j<13 ; j++ )
		{
			name[j] = path[i+1+j] ;
		}
	}

	ret = FDG_SetFileText( name ) ;
	ret = FDG_SetTitle( title, exec, cncl ) ;
	ret = FDG_DspFileDlg(MMI_GetBaseObj(), FDG_FILEONLY | FDG_TEXT,
		 pathName, ExtStr,	&MSlctCnt) ;
	if( ret < 0 )	/* PATHが間違ってる場合はカレントディレクトリで */
	{
		name[0] = '\0' ;
		ret = FDG_SetFileText( name ) ;
		ret = FDG_DspFileDlg(MMI_GetBaseObj(), FDG_FILEONLY | FDG_TEXT,
			 NULL, ExtStr,	&MSlctCnt) ;
	}

	if( (ret == 1) && (MSlctCnt > 0) )	/*	正しくファイル名を収得したか？	*/
	{
		FDG_GetPathName( path, &Atr, 0 ) ;
	}
	else
	{
		ret2 = 1 ;
	}
	ret = FDG_RecovCurDir() ;
	return ret2 ;
}

/*	パレット設定 */

int	setPalette( char *ework )
{
	char	para[16*8+4] ;
	int		ptr, colnum ;

	void 	set1Pal( int col, int b, int r, int g )
	{
		DWORD(para + ptr) = col ;
		BYTE(para + ptr + 4) = b * 16 ;
		BYTE(para + ptr + 5) = r * 16 ;
		BYTE(para + ptr + 6) = g * 16 ;
		BYTE(para + ptr + 7) = 0 ;
		ptr += 8 ;
	}

//	EGB_getTmenuPalette( para ) ;
//	colnum = DWORD(para) ;

	colnum = 0 ;		/* 強制的に色設定にしてしまう 1993 12 */

	if( colnum == 6 )	ptr = 52 ;
	else				ptr = 4 ;
	if( colnum != 16 )
	{
		set1Pal( 2, 4, 12, 6 ) ;
		set1Pal( 3, 5, 5, 5 ) ;		// 		set1Pal( 3, 10, 15, 12 ) ;
		set1Pal( 4, 9, 9, 9 ) ;
		set1Pal( 5, 7, 0, 12 ) ;
		set1Pal( 10, 0, 13, 0 ) ;
		set1Pal( 11, 10, 0, 0 ) ;
		set1Pal( 12, 0, 0, 15 ) ;
		set1Pal( 13, 15, 0, 15 ) ;
		set1Pal( 14, 0, 15, 13 ) ;
		if( colnum != 6 )
		{		/* メニュー色(green系) */
			set1Pal( 1, 4, 4, 8 ) ;
			set1Pal( 6, 12, 12, 12 ) ;
			set1Pal( 7, 7, 7, 7 ) ;
			set1Pal( 8, 2, 2, 2 ) ;
			set1Pal( 9, 8, 10, 12 ) ;	/* file selector */
			set1Pal( 15, 15, 15, 15 ) ;
		}
		DWORD(para + 0) = 15 ;
	}
	else
		DWORD(para + 0) = colnum ;
	EGB_palette( ework, 1, para ) ;

	return NOERR ;
}

/* 準備 */

int startSet()
{
	extern int recTimeNumId ;
	extern int recRateNumId ;
	extern int voicMulNumId ;
	extern int voicMulVolumeId ;
	extern int harmMulNumId ;
	extern int harmMulVolumeId ;
	extern int pitchMulNumId ;
	extern int pitchMulVolumeId ;
	extern int sampRateNumId ;
	extern int headNumId[6] ;
	extern int fadeNumId[4] ;

	int ret, timeMax ;
	int var, min, max, delta, ptColumn ;
	int len, page, i ;

	/* サウンドバッファの確保 */

	ret = getBuffer() ;
	if( ret )return ret ;

	/* GUI EDITORの不備のため設定できない部分を設定 */

	/* rec */
	timeMax = ( sndBufSize - 32 ) / 19200 * 10 ;

	MMI_SendMessage( recTimeNumId, MM_GETNUMBOX, 5, /* 録音時間 */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( recTimeNumId, MM_SETNUMBOX, 5, /* 変更 */
							var, min, timeMax, delta, ptColumn ) ;

	MMI_SendMessage( recRateNumId, MM_GETNUMBOX, 5, /* サンプリングレート */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( recRateNumId, MM_SETNUMBOX, 5, /* 変更 */
							19200, min, 19200, delta, ptColumn ) ;

	/* voice change */
	MMI_SendMessage( voicMulNumId, MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( voicMulNumId, MM_SETNUMBOX, 5,
							300, -1600, 1600, delta, ptColumn ) ;

	MMI_SendMessage( voicMulVolumeId, MM_GETSCROLL, 5,
							&var, &min, &max, &len, &page ) ;
	MMI_SendMessage( voicMulVolumeId, MM_SETSCROLL, 5,
							30, -160, 160, len, page ) ;

	/* harmony */
	MMI_SendMessage( harmMulNumId, MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( harmMulNumId, MM_SETNUMBOX, 5,
							300, -1600, 1600, delta, ptColumn ) ;

	MMI_SendMessage( harmMulVolumeId, MM_GETSCROLL, 5,
							&var, &min, &max, &len, &page ) ;
	MMI_SendMessage( harmMulVolumeId, MM_SETSCROLL, 5,
							30, -160, 160, len, page ) ;

	/* pitch */
	MMI_SendMessage( pitchMulNumId, MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( pitchMulNumId, MM_SETNUMBOX, 5,
							300, -1600, 1600, delta, ptColumn ) ;

	MMI_SendMessage( pitchMulVolumeId, MM_GETSCROLL, 5,
							&var, &min, &max, &len, &page ) ;
	MMI_SendMessage( pitchMulVolumeId, MM_SETSCROLL, 5,
							30, -160, 160, len, page ) ;

	/* sampling rate set */
	MMI_SendMessage( sampRateNumId, MM_GETNUMBOX, 5, /* サンプリングレート */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( sampRateNumId, MM_SETNUMBOX, 5, /* 変更 */
							19200, min, 50000, delta, ptColumn ) ;

	/* write head */
	MMI_SendMessage( headNumId[0], MM_GETNUMBOX, 5,	/* data length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( headNumId[0], MM_SETNUMBOX, 5, /* 変更 */
							var, min, sndBufSize - 32, delta, ptColumn ) ;
	MMI_SendMessage( headNumId[1], MM_GETNUMBOX, 5,	/* loop point */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( headNumId[1], MM_SETNUMBOX, 5, /* 変更 */
							var, min, sndBufSize - 32, delta, ptColumn ) ;
	MMI_SendMessage( headNumId[2], MM_GETNUMBOX, 5,	/* loop length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( headNumId[2], MM_SETNUMBOX, 5, /* 変更 */
							var, min, sndBufSize - 32, delta, ptColumn ) ;
	MMI_SendMessage( headNumId[3], MM_GETNUMBOX, 5,	/* freq */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( headNumId[3], MM_SETNUMBOX, 5, /* 変更 */
							var, min, 65535, delta, ptColumn ) ;
	MMI_SendMessage( headNumId[4], MM_GETNUMBOX, 5,	/* add freq (WORD) */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( headNumId[4], MM_SETNUMBOX, 5, /* 変更 */
							var, -32768, 32767, delta, ptColumn ) ;
	MMI_SendMessage( headNumId[5], MM_GETNUMBOX, 5,	/* pitch (BYTE) */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( headNumId[5], MM_SETNUMBOX, 5, /* 変更 */
							var, min, 255, delta, ptColumn ) ;

	/* fade in & out */
	for( i=0 ; i<4 ; i++ )
	{
		MMI_SendMessage( fadeNumId[i], MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
		MMI_SendMessage( fadeNumId[i], MM_SETNUMBOX, 5, /* 変更 */
							var, min, 999999, delta, ptColumn ) ;
	}

	return NOERR ;
}

int getBuffer()
{
	SNDHEAD *head ;

	char *p ;
	int i, block, max ;

	block = TL_checkMemory( 2 ) ;

	p = NULL ;
	for( i=block ; i>0 ; i-- )
	{
		max = i*4096 ;
		p = (char *)TL_malloc( max ) ;
		if( p != NULL )break ;
	}
	if( p == NULL )return OUT_OF_MEMORY ;
	TL_free( p ) ;
//	max -= 4096*100 ;		/* GUIのために,適当に400kの余裕を取ってあげる */
	max -= 2048*100 ;		/* GUIのために,適当に200kの余裕を取ってあげる */
	if( max < 0 )return OUT_OF_MEMORY ;
	p = (char *)TL_malloc( max ) ;
	if( p == NULL )return OUT_OF_MEMORY ;

	sndBufSize = max / 2 ;
	sndBuf1 = p ;
	sndBuf2 = p + sndBufSize ;

	if( sndBufSize < 512 )return OUT_OF_MEMORY ;
	sndBufSize -= 256 ;			/* 256Byteはクッションに開けておく */

	head = (SNDHEAD *)sndBuf1 ;		/* 架空のデータを入れて万が一を防ぐ */
	for( i=0 ; i<8 ; i++ )
		head->name[i] = '\0' ;
	head->id = 0 ;
	head->length = 0 ;
	head->looppoint = 0 ;
	head->looplength = 0 ;
	head->freq = 0 ;
	head->adjust = 0 ;
	head->note = 0 ;
	head = (SNDHEAD *)sndBuf2 ;		/* 架空のデータを入れて万が一を防ぐ */
	for( i=0 ; i<8 ; i++ )
		head->name[i] = '\0' ;
	head->id = 0 ;
	head->length = 0 ;
	head->looppoint = 0 ;
	head->looplength = 0 ;
	head->freq = 0 ;
	head->adjust = 0 ;
	head->note = 0 ;

	return NOERR ;
}

/*	終了処理	*/

int	quitFunc()
{
	MMI_SetHaltFlag( TRUE ) ;

	return NOERR ;
}

/*	あばうと表示	*/

int	aboutFunc()
{
	MMI_SendMessage( alertId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( alertId, MM_SHOW, 0 ) ;

	MMI_ExecSystem() ;

	MMI_SendMessage( alertId, MM_ERASE, 0 ) ;
	MMI_SendMessage( alertId, MM_DETACH, 0 ) ;
	return NOERR ;
}

/*	あばうと表示確認	*/

int	aboutOKFunc(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;

	return NOERR ;
}

/* 情報表示 */

sndInf()
{
	SNDHEAD *head ;
	int var, min, max, delta, ptColumn ;
	int f ;

	head = (SNDHEAD *)sndBuf1 ;

	MMI_SendMessage( infNumId[0], MM_GETNUMBOX, 5, /* data length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[0], MM_SETNUMBOX, 5,
						head->length, 0, head->length, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[1], MM_GETNUMBOX, 5, /* length point */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[1], MM_SETNUMBOX, 5,
					head->looppoint, 0, head->looppoint, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[2], MM_GETNUMBOX, 5, /* loop length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[2], MM_SETNUMBOX, 5,
					head->looplength, 0, head->looplength, delta, ptColumn ) ;

	f = ( head->freq ) * 1000 / 0x62 ;				/* freq */
	f = ( f + 50 )/100 * 100 ;		/* 10の位を四捨五入 */
	MMI_SendMessage( infNumId[3], MM_GETNUMBOX, 5, /* loop length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[3], MM_SETNUMBOX, 5,
									f, 0, f, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[4], MM_GETNUMBOX, 5, /* loop length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[4], MM_SETNUMBOX, 5,
					head->adjust, -32768, 32767, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[5], MM_GETNUMBOX, 5, /* loop length */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[5], MM_SETNUMBOX, 5,
					head->note, 0, head->note, delta, ptColumn ) ;


	MMI_SendMessage( infDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( infDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( infDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( infDialogId, MM_DETACH, 0 ) ;

	return NOERR ;
}

/* 情報確認 */

int	infOkFunc(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/* error 表示ルーチン */

int errorCheck(number)
int number;
{
	/*
	#define	OUT_OF_MEMORY		7
	#define	ILLIGAL_FILENAME	55
	#define	ILLIGAL_DATA		58
	#define	CANT_LOAD			1
	#define	CANT_SAVE			2
	*/

	MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "エラーが発生しました｡" ) ;
	if( number == OUT_OF_MEMORY )
		MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "メモリが足りません。" ) ;
	if( number == ILLIGAL_FILENAME )
		MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "ファイル名が正しくありません｡" ) ;
	if( number == ILLIGAL_DATA )
		MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "データ形式が正しくありません｡" ) ;
	if( number == CANT_LOAD )
		MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "ロードできませんでした｡" ) ;
	if( number == CANT_SAVE )
		MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "セーブできませんでした｡" ) ;

	MMI_SendMessage( errorId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( errorId, MM_SHOW, 0 ) ;

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( errorId, MM_ERASE, 0 ) ;
	MMI_SendMessage( errorId, MM_DETACH, 0 ) ;

	return NOERR;
}

/*	エラー表示確認	*/

int	errorOKFunc(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;

	return NOERR ;
}

/* マウスボタンチェック */

mouseSwCheck()
{
	int sw ;

	SND_joy_in_1( 0x01, &sw );
	sw = ((sw ^ 0xff) & 0x30) >> 4 ;
	return sw ;
}

/* アンドゥ用にデータを退避 */

sndBufTrans()
{
	SNDHEAD *head ;

	head = (SNDHEAD *)sndBuf1 ;
	if( (head->length) > (sndBufSize - 32) )
		head->length = sndBufSize - 32 ;
	sndTransfer( sndBuf1, sndBuf2 ) ;

	return NOERR ;
}

/* アンドゥ */

unDo()
{
	SNDHEAD *head ;

	head = (SNDHEAD *)sndBuf2 ;
	if( (head->length) > (sndBufSize - 32) )
		head->length = sndBufSize - 32 ;
	sndTransfer( sndBuf2, sndBuf1 ) ;

	return NOERR ;
}

/* 再生 */

sndPlay()
{
	SNDHEAD *head ;
	int sw, st ;

	head = (SNDHEAD *)sndBuf1 ;

	if( (head->freq) <= 0 )return NOERR ;
						/* ｻﾝﾌﾟﾘﾝｸﾞﾚｰﾄが小さい場合は実行しない */

	SND_elevol_mute( 0x00000001 ) ;
	SND_pcm_sound_delete( -1 );
	SND_pcm_mode_set( 1 );
//	SND_pcm_play( 71, head->note, 127, sndBuf1 );
	SND_pcm_play2( 71, head->note, 127, sndBuf1 );

	while( mouseSwCheck() ) ;

	do					  				/* ループ開始 */
	{
		sw = mouseSwCheck() ;  		/* マウス情報読み込み */
		st = SND_pcm_status( 71 ) ; 	/* 再生状態入手 */
	}
	while( (sw == 0) && (st != 0) ) ;
       /* 再生終了になるか,マウスボタンが押されるまでループする */

	SND_pcm_play_stop( 71 ) ;			/* 再生をストップする */
	SND_elevol_mute( 0x00000000 ) ;
	return NOERR ;
}

/* メッセージのカラーを変えて表示する */

setMsgColor( int kobj, int color )
{
	OBJECT *pobj ;
	MSGL40 *data ;

	pobj = TL_getObjectPtr( kobj ) ;
	data = (MSGL40 *)(pobj->data) ;
	data->clr.ch = color ;
	MMI_SendMessage( kobj, MM_SHOW, 0 ) ;	/* 見せる */

	return NOERR ;
}

