/* 音姫 main sub 1994 11/30 */

#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 <wav.h>
#include "wavhime.h"
#include "otolib.h"

/* about */
int	alertId = -1 ;
int	messageId[3] = -1 ;
int	dspIconId = -1 ;
int	aboutOKBtnId = -1 ;

/* information */
int	infDialogId = -1 ;
int	infMsgId[7] = -1 ;
int	infNumId[5] = -1 ;
int	infOkBtnId = -1 ;

/* desk */
int	baseDialogId = -1 ;
int	menubarId = -1 ;
int	menuId = -1 ;
int	mItemId[3] = -1 ;
int	SDKmenuId = -1 ;
int	SDKmItemId[4] = -1 ;
int	fileMenuId = -1 ;
int	fileMItemId[8] = -1 ;
int	effMenuId = -1 ;
int	effMItemId[15] = -1 ;
int	quitIconId = -1 ;

/* error */
int	errorId = -1 ;
int	errorOKBtnId = -1 ;
int	errorIconId = -1 ;
int	errormessage[2] = -1 ;

	/* 各コマンド呼び出し */

int tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */

char sndFileName[100] = " " ;
char sndBufFile1[100] = "temp1.tmp" ;
char sndBufFile2[100] = "temp2.tmp" ;

/*
 テンポラリファイルの名前を作る
 dirにディレクトリorフルネームを入れておくこと
 */

int tempFileSet( int ac, char *av[], char *dir )
{
	int i, j ;
	int s ;
	int error ;
	char tp1[16] = "TEMP1.TMP" ;
	char tp2[16] = "TEMP2.TMP" ;
	char path[100] ;

	for( i=0 ; i<80 ; i++ )
	{
		path[i] = dir[i] ;
		if( path[i] == '\0' )break ;
	}

	if( ac >= 3 )
	{
	    for( j=1 ; j<ac ; j++ )
	    {
			if( av[j][0] == '-' )
			{
				s = av[j][1] ;
				if( s >= 0x61 && s <= 0x7a )s = s & 0xdf;

				if( s == 'T' )
				{
					if( (av[j][2] == '\0') && ( (j+1) < ac ) )
					{
						for( i=0 ; i<80 ; i++ )
						{
							path[i] = av[j+1][i] ;
							if( path[i] == '\0' )break ;
						}

						if( i > 0 )
						{
							if( path[i-1] != '\\' )
							{
								path[i] = '\\' ;
								path[i+1] = '\0' ;
							}
						}
					}

					if( (av[j][2] == '1') && ( (j+1) < ac ) )
					{
						for( i=0 ; i<13 ; i++ )
						{
							tp1[i] = av[j+1][i] ;
							if( tp1[i] == '\0' )break ;
						}
					}

					if( (av[j][2] == '2') && ( (j+1) < ac ) )
					{
						for( i=0 ; i<13 ; i++ )
						{
							tp2[i] = av[j+1][i] ;
							if( tp2[i] == '\0' )break ;
						}
					}
				}
			}
		}
	}

	for( j=0 ; j<80 ; j++ )
	{
		if( path[j] == '\0' )
			break ;
	}
	if( j > 79 )j = 79 ;
	for( i=j ; i>=0 ; i-- )
	{
		if( path[i] == '\\' )
			break ;
	}

	if( i >= 0 )
	{
		for( j=0 ; j<=i ; j++ )
		{
			sndBufFile1[j] = path[j] ;
			sndBufFile2[j] = path[j] ;
		}

		for( i=0 ; i<13 ; i++ )
		{
			sndBufFile1[j+i] = tp1[i] ;
			if( sndBufFile1[j+i] == '\0' )break ;
		}

		for( i=0 ; i<13 ; i++ )
		{
			sndBufFile2[j+i] = tp2[i] ;
			if( sndBufFile2[j+i] == '\0' )break ;
		}
	}

	if( wavWriteReadCheck() == ILLIGAL_DATA )
	{
	    remove( sndBufFile1 ) ;
    	remove( sndBufFile2 ) ;
		tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */
		errorCheck2( "ＷＡＶを扱える環境になってません｡" ) ;
		error = ILLIGAL_DATA ;
	}
	else
	{
	    remove( sndBufFile1 ) ;
    	remove( sndBufFile2 ) ;
		tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */
		error = NOERR ;
	}

	return error ;
}

static int wavWriteReadCheck()
{
    FILE  *pFile ;                      //  ファイルポインタ

	char head[512] ;

    int   ret ;                         //  戻り値
    int   freq = 44100 ;                    //  サンプリング周波数
    int   bitno = 16 ;                   //  サンプリングビット数
    int   kind = 2 ;                    //  データ種別
    int   pcmsz = 4096*16 ;                   //  PCMデータサイズ
    int   pcmstart ;                    //  PCMデータ相対開始位置
    int   error ;

	error = NOERR ;

    if ( (pFile = fopen( sndBufFile1, "wb" )) == NULL )  //  ファイル作成
    {
		error = CANT_SAVE ;
        goto WRITE_2 ;
    }
    //  WAVEファイルの情報を作成しファイルに書きだす
    WAV_setWaveInfo_2( head, freq, bitno, kind, pcmsz, &pcmstart ) ;
    if ( fwrite( head, 1, 44, pFile) != 44 )
    {
		error = CANT_SAVE ;
        goto WRITE_3 ;
    }

WRITE_3: ;
    fclose( pFile ) ;
WRITE_2: ;

	if( error )
	{
		return error ;
	}

    //  再生ファイルをオープンする
    if ( (pFile = fopen( sndBufFile1, "rb" )) == NULL )  //  ファイルオープン
    {
        error = NO_DATA ;
        goto FILEFIN_2 ;
    }

    //  ファイルの情報を取得する
    if( fread( head, 1, 44, pFile ) != 44 )
    {
	    error = CANT_LOAD ;
        goto FILEFIN_3 ;
    }
    ret = WAV_getWaveInfo( head, 44, &freq, &bitno, &kind,
                                                     &pcmsz, &pcmstart) ;
	if( ret == 23 )
    {
        error = ILLIGAL_DATA ;
        goto FILEFIN_3 ;
    }

	if( (freq != 44100) || (bitno != 16) || (kind != 2) || (pcmsz != 4096*16) )
	{
        error = ILLIGAL_DATA ;
        goto FILEFIN_3 ;
    }

//  後処理
FILEFIN_3 :;
    fclose( pFile ) ;
FILEFIN_2 :;
FILEFIN_1 :;
	return error ;
}

/* ファイル */

/* load */
int	selectFunc0(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	char *ExtStr[] = { "*.WAV", "*.SND", NULL } ;
	int ret ;

	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	ret = fileSelecter( sndFileName, ExtStr,
							"読  込", "実  行", "取  消");

	if( ret == NOERR )
	{
		delTemp2() ;
		temp1_to_temp2() ;		/* temp1をtemp2へ */

		SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */

		if( get_file_kakucho( sndFileName ) == DWORD( ".WAV" ) )
			ret = wavFileTrans( sndFileName, sndBufFile1 ) ;

		if( get_file_kakucho( sndFileName ) == DWORD( ".SND" ) )
			ret = loadSndDataFile( sndFileName ) ;

		SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */
		if( ret )
			errorCheck( ret ) ;
		else
		{
			tempFileCount++ ;		/* 現在作られてるテンポラリファイルの数 */
			if( tempFileCount > 2 )
				tempFileCount = 2 ;
		}
	}

	/* メニューとボタンを使えるように戻す */
	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 *ExtStr[] = { "*.WAV", "*.SND", NULL } ;
	int ret ;

	if( delTemp2() != NOERR )
	{
		errorCheck( NO_DATA ) ;
		return NOERR ;
	}

	/* メニューとボタンを使えないようにする */
	MTL_setAtrObj( menubarId, MS_DSPONLYL40 ) ;
	MTL_setAtrObj( SDKmItemId[2], MS_INACTIVEL40 ) ;

	ret = fileSelecter( sndFileName, ExtStr,
							"読  込", "実  行", "取  消");

	if( ret == NOERR )
	{
		sndMix( sndFileName ) ;
	}

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	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[] = { "*.WAV", 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, ".WAV" ) ;
		for( i=0 ; i<100 ; i++ )
			sndFileName[i] = path[i] ;

		SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
		ret = wavFileTrans( sndBufFile1, sndFileName ) ;
		SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */
		if( ret )
			errorCheck( ret ) ;
	}

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	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 ) ;

	delTemp2() ;
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectEcho() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectPhaseShift() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectVibrato() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectTremolo() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectVoiceChange() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectHarmony() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectExpand() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectLevel() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectPitch() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectFade() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	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 ) ;

	if( delTemp2() == NOERR )
		sndEffectSampSet() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* trimming */
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 ) ;

	if( delTemp2() == NOERR )
		sndEffectTrim() ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* fft */
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 ) ;

	if( delTemp2() == NOERR )
		sndEffectFft( sndFileName ) ;
	else
		errorCheck( NO_DATA ) ;

	/* メニューとボタンを使えるように戻す */
	MTL_resetAtrObj( menubarId, (~MS_DSPONLYL40) ) ;
	MTL_resetAtrObj( SDKmItemId[2], (~MS_INACTIVEL40) ) ;

	return NOERR ;
}

/* undo */
int	effFunc99(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( char *fullname, char *name, char *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;
}

/* return DWORD( ".拡張子" ) */

int get_file_kakucho( char *name )
{
	int i, j, f ;
	char kaku[4] ;

	for( i=0 ; i<4 ; i++ )kaku[i] = (char)0;
	f = 0 ;
	for( j=0 ; j<80 ; j++ ){
		if( name[j] == '.' )f = 1 ;
		if( name[j] == '\0' )break ;
	}
	if( f == 0 )return 0;		/* 拡張子なし */
	if( j > 79 )j = 79 ;
	for( i=j ; i>0 ; i-- )	/* 日本語の混乱を避けるため終わりからスキャン */
	{
		if( name[i] == '.' )goto mov01;
	}
	return 0;		/* 拡張子なし */
mov01:	if( i == 0 )return 0;
	for( j=0 ; j<4 ; j++ ){
		if( name[i] == '\0' )break ;
		kaku[j] = name[i];
		i++;
		if( (int)kaku[j] >= 0x61 && (int)kaku[j] <= 0x7a )
		    kaku[j] = (char)( (int)kaku[j] & 0xdf ); /* 大文字化 */
	}
	return DWORD( kaku );
}

/*	ファイル選択	*/

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 ;
	int alertobj ;  /*  ALERTOBJ退避  */

	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 ) ;

	alertobj = MMI_GetAlertObj() ;  /*  現在のALERTOBJを退避  　  */
	MMI_SetAlertObj( FDG_GetMainID() ) ;

	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) ;
	}

	MMI_SetAlertObj( alertobj ) ;  /*  ALERTOBJを元に戻す    　   */

	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 voicMulNumId ;
	extern int voicMulVolumeId ;
	extern int harmMulNumId ;
	extern int harmMulVolumeId ;
	extern int pitchMulNumId ;
	extern int pitchMulVolumeId ;
	extern int fadeNumId[4] ;
	extern int trimNumId[2] ;
	extern int fftTimeNumId ;
	extern int fftPointNumId ;

	int timeMax ;
	int var, min, max, delta, ptColumn ;
	int len, page, i ;

	/* GUI EDITORの不備のため設定できない部分を設定 */

	/* rec */
	timeMax = 99999 ;

	MMI_SendMessage( recTimeNumId, MM_GETNUMBOX, 5, /* 録音時間 */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( recTimeNumId, MM_SETNUMBOX, 5, /* 変更 */
							var, min, timeMax, 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 ) ;

	/* 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 ) ;
	}

	/* trim in & out */
	for( i=0 ; i<2 ; i++ )
	{
		MMI_SendMessage( trimNumId[i], MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
		MMI_SendMessage( trimNumId[i], MM_SETNUMBOX, 5, /* 変更 */
							var, min, 999999, delta, ptColumn ) ;
	}

	/* fft */
	MMI_SendMessage( fftTimeNumId, MM_GETNUMBOX, 5,
						&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( fftTimeNumId, MM_SETNUMBOX, 5, /* 変更 */
						var, min, 999999, delta, ptColumn ) ;

	MMI_SendMessage( fftPointNumId, MM_GETNUMBOX, 5,
						&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( fftPointNumId, MM_SETNUMBOX, 5, /* 変更 */
						var, min, 99999999, delta, ptColumn ) ;

	return NOERR ;
}

/* スリープ時の設定 */
int sleepSet()
{
//	WAV_end() ;            //  WAVEライブラリの初期化
	return NOERR ;
}

/* 起こされた時の設定 */
int wakeSet()
{
//	WAV_init() ;            //  WAVEライブラリの初期化
	return NOERR ;
}

/*	終了処理	*/
int	quitFunc()
{
	/* テンポラリファイルを消す */
	remove( sndBufFile1 ) ;
	remove( sndBufFile2 ) ;
	tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */

	MMI_SetHaltFlag( TRUE ) ;

	return NOERR ;
}

/*	終了可能なら終了する処理	*/
int	quitFunc2()
{
	if( MTL_checkAtrObj( menubarId, MS_DSPONLYL40 ) == 0 )
	{
		/* テンポラリファイルを消す */
		remove( sndBufFile1 ) ;
		remove( sndBufFile2 ) ;
		tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */

		MMI_SetHaltFlag( TRUE ) ;

		return NOERR ;
	}
	return ILLEGAL_FUNCTION ;
}

/*	あばうと表示	*/

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()
{
	int var, min, max, delta, ptColumn ;

    int   freq = 0 ;                    //  サンプリング周波数
    int   bitno = 0 ;                   //  サンプリングビット数
    int   kind = 0 ;                    //  データ種別
    int   pcmsz = 0 ;                   //  PCMデータサイズ
    int   pcmstart ;                    //  PCMデータ相対開始位置
    int   time ;
    int   error ;

	error =
	readInfo( sndBufFile1, &freq, &bitno, &kind, &pcmsz, &pcmstart );

	if( error )
	{
		errorCheck( error ) ;
		return NOERR ;
	}

	MMI_SendMessage( infNumId[0], MM_GETNUMBOX, 5, /* freq */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[0], MM_SETNUMBOX, 5,
							freq, 0, freq, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[1], MM_GETNUMBOX, 5, /* bit */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[1], MM_SETNUMBOX, 5,
							bitno, 0, bitno, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[2], MM_GETNUMBOX, 5, /* ch 数 */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[2], MM_SETNUMBOX, 5,
							kind, 0, kind, delta, ptColumn ) ;

	MMI_SendMessage( infNumId[3], MM_GETNUMBOX, 5, /* size */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[3], MM_SETNUMBOX, 5,
							pcmsz, 0, pcmsz, delta, ptColumn ) ;

	if( (bitno * kind * freq ) != 0 )
		time = pcmsz*10/(bitno/8*kind)/freq ;
	else
		time = 0 ;
	MMI_SendMessage( infNumId[4], MM_GETNUMBOX, 5, /* time */
							&var, &min, &max, &delta, &ptColumn ) ;
	MMI_SendMessage( infNumId[4], MM_SETNUMBOX, 5,
							time, 0, time, 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 表示ルーチン */

static int errorCheckMode = 0 ;

int errorCheck( int number )
{
	/*
	#define	OUT_OF_MEMORY		7
	#define	ILLIGAL_FILENAME	55
	#define	ILLIGAL_DATA		58
	#define	CANT_LOAD			1
	#define	CANT_SAVE			2
	#define	NO_DATA				63
	*/

	errorCheckMode = 0 ;

	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,
		 "セーブできませんでした｡" ) ;
	if( number == NO_DATA )
		MMI_SendMessage( errormessage[0], MM_SETMSG, 1,
		 "データが存在しません｡" ) ;

	MMI_SendMessage( errorId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( errorId, MM_SHOW, 0 ) ;

//	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */
//  キー却下時onがある時にはこの方式はだめ
//	MMI_SendMessage( errorId, MM_ERASE, 0 ) ;
//	MMI_SendMessage( errorId, MM_DETACH, 0 ) ;

	return NOERR;
}

int errorCheck2( char *name )
{
	errorCheckMode = 1 ;

	MMI_SendMessage( errormessage[0], MM_SETMSG, 1, name ) ;

	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 ;
{
	if( errorCheckMode == 0 )
	{
		MMI_SendMessage( errorId, MM_ERASE, 0 ) ;
		MMI_SendMessage( errorId, MM_DETACH, 0 ) ;
	}
	else
	{
		MMI_SetHaltFlag( TRUE ) ;

		MMI_SendMessage( errorId, MM_ERASE, 0 ) ;
		MMI_SendMessage( errorId, MM_DETACH, 0 ) ;
	}
	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 ;
}

/* マウスボタンチェック */

mouseSwCheck()
{
	int sw ;

	SND_joy_in_1( 0x01, &sw );
	sw = ((sw ^ 0xff) & 0x30) >> 4 ;
	return sw ;
}

/* テンポラリファイル1を2にする */

temp1_to_temp2()
{
	int ret ;

	ret = NOERR ;
	remove( sndBufFile2 ) ;
	if( rename( sndBufFile1, sndBufFile2 ) )
	{
		ret = NO_DATA;
		tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */
	}
	else
	{
		tempFileCount = 2 ;		/* 現在作られてるテンポラリファイルの数 */
	}

	return ret ;
}

/* テンポラリファイル2を消す */

delTemp2()
{
    FILE  *pFile ;                      //  ファイルポインタ
	int ret ;

	ret = NOERR ;
	remove( sndBufFile2 ) ;
    //  再生ファイルをオープンする
    if ( (pFile = fopen( sndBufFile1, "rb" )) == NULL )  //  ファイルオープン
    {
		ret = NO_DATA ;
		tempFileCount = 0 ;		/* 現在作られてるテンポラリファイルの数 */
    }
    else
    {
		tempFileCount = 1 ;		/* 現在作られてるテンポラリファイルの数 */
	    fclose( pFile ) ;
    }

	return ret ;
}

/* アンドゥ */

unDo()
{
    FILE  *pFile ;                      //  ファイルポインタ

    //  再生ファイルをオープンする
    if ( (pFile = fopen( sndBufFile2, "rb" )) != NULL )  //  ファイルオープン
    {
	    fclose( pFile ) ;
		remove( sndBufFile1 ) ;
		rename( sndBufFile2, sndBufFile1 ) ;
		tempFileCount = 1 ;		/* 現在作られてるテンポラリファイルの数 */
    }

	return NOERR ;
}

/* 再生 */

sndPlay()
{
	int ret ;

    WAV_setVolume( 127, 127 ) ;                       //  再生音量の設定
	ret = playfile() ;

	if( ret < 0 )
	{
		errorCheck2( "規格外のサンプリングレートです｡" ) ;
		ret =  NOERR ;
	}

	return ret ;
}

static int n_count ;

//  同期関数
//  注意：この同期関数のアドレスが０の場合、NULL指定と誤判断されるので、
//        この関数の位置には注意が必要
void  syncfunc()
{
    n_count ++ ;
    return ;
}

// 直接ファイルから再生
// 規格外のサンプリングレートならマイナスの値を返す
int  playfile()
{
    FILE  *pFile ;                      //  ファイルポインタ
    char  *pring ;                      //  リングバッファポインタ
    struct    buf_ctrl
    {
        int   sum ;
        int   apply_loc ;
        int   system_loc ;
        struct
        {
            char  *ptr ;
            char  reserve[8] ;
        }   buftbl[2] ;
    }   *pctrl ;                       //  リングバッファ管理テーブルポインタ
    int   ret ;                         //  戻り値
    int   ch, x, y ;                    //  マウス用変数
    int   remain ;                      //  残りサンプリングデータサイズ
    int   fl = 0 ;                      //  無限ループフラグ
    int   status ;                      //  ステータス
    int   nextloc ;                     //  次回のアプリケーション位置
    int   freq ;                        //  サンプリング周波数
    int   bitno ;                       //  サンプリングビット数
    int   kind ;                        //  データ種別
    int   pcmsz ;                       //  PCMデータサイズ
    int   pcmstart ;                    //  PCMデータ相対開始位置
    int   rdsz ;                        //  読み込むデータサイズ
    int   rdsize ;                      //  読み込まれたデータサイズ
    int   error ;

	error = NOERR ;

    //  リングバッファとリングバッファ管理テーブルの領域の確保を行う
    //  リングバッファ数は16個
/*
    if ( (pring = TL_malloc( (16+1)*4096 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }
    if ( (pctrl = (struct buf_ctrl *)TL_malloc( (16+1)*12 )) == NULL )
    {
        error = OUT_OF_MEMORY ;
        goto FILEFIN_1 ;
    }
*/
/*
	int lot ;

	lot = TL_getLot() ;
	if( (pring = (char *)TL_mallocMemory( lot, (16+1)*4096 + (16+1)*12 ))
																 == NULL )
    {
		if( lot )
			TL_freeLot( lot ) ;
        return OUT_OF_MEMORY ;
    }
    pctrl = (struct buf_ctrl *)( pring +  (16+1)*4096 ) ;
*/

// シェル対応のプログラムの場合ワークは,auto変数 or static変数を
// 使わないとWAV関数とうまくいかないこともある.何故かはわからない
	char buffer[ (16+1)*4096 + (16+1)*12 + 1024 ] ;
	pring = buffer ;
	pctrl = (struct buf_ctrl *)( buffer + (16+1)*4096 +512 );

    //  リングバッファ管理テーブルの作成
    pctrl->sum = 16 ;                        //  バッファ総数の設定
    pctrl->apply_loc = 0 ;                   //  アプリケーション位置のクリア
    WAV_makeTable( pring, (char *)pctrl ) ;

    //  再生ファイルをオープンする
    if ( (pFile = fopen( sndBufFile1, "rb" )) == NULL )  //  ファイルオープン
    {
        error = CANT_LOAD ;
        goto FILEFIN_2 ;
    }

    //  リングバッファを使用してファイルの情報を取得する
    rdsz = 0 ;
    do
    {
        rdsz += 50 ;
        //  ファイルポインタをWAVEデータの先頭に位置づける
        ret = fseek( pFile, 0, SEEK_SET ) ;
        if ( ret != 0 )
        {
	        error = CANT_LOAD ;
            goto FILEFIN_3 ;
        }
        rdsize = fread( pring, 1, rdsz, pFile ) ;

        if ( rdsize != rdsz )
        {
	        error = CANT_LOAD ;
            goto FILEFIN_3 ;
        }
        ret = WAV_getWaveInfo( pring, rdsz, &freq, &bitno, &kind,
                                                     &pcmsz, &pcmstart) ;
	} while( ret == 23 ) ;

	if( ret == 23 )
    {
        error = ILLIGAL_DATA ;
        goto FILEFIN_3 ;
    }

	if( (freq != 44100) && (freq != 22050) && (freq != 11025) )
	{
        error = -ILLIGAL_DATA ;		// 規格外のサンプリングレート
        goto FILEFIN_3 ;
    }

    //  ファイルポインタをPCMデータの先頭に位置づける
    ret = fseek( pFile, pcmstart, SEEK_SET ) ;
    if ( ret != 0 )
    {
        error = CANT_LOAD ;
        goto FILEFIN_3 ;
    }

    //  再生データをリングバッファ分先読みしておく
    rdsz = 16*4096 ;
    if ( rdsz > pcmsz )  rdsz = pcmsz ;
    if ( (rdsize = fread( pctrl->buftbl[pctrl->apply_loc].ptr,
                                1, rdsz, pFile )) != rdsz )
    {
        error = CANT_LOAD ;
        goto FILEFIN_3 ;
    }

    //  再生前準備
    remain = pcmsz - rdsize ;	//  残りPCMデータサイズ設定
    n_count = 0 ;				//  カウンタ値のクリア
    nextloc = 4 ;				//  次回のアプリケーション位置の設定
    rdsz = 4*4096 ;				//  一回当たりのファイル読み込みサイズ
    WAV_playPrepare( freq, bitno, kind, NULL, syncfunc ) ;

    //  再生開始
    WAV_play( pcmsz ) ;                               //  再生を行う

    //  指定サイズ再生されるまで繰り返す
    while( fl == 0 )
    {
        MOS_rdpos(&ch, &x, &y) ;
        if( ch )
			WAV_playStop() ;

        WAV_getStatus( &status ) ;
        if ( !( status & WAV_ST_PLAY_PROCESS ) )   //  再生処理が終了していれば
            fl++ ;                                 //  flに1設定

        //  リングバッファ４個分再生されていればファイルからデータを読みだす
        if ( ( remain > 0 ) && ( n_count >= 4 ) )
        {
            n_count -= 4 ;                            //  カウンタ値の再設定
                                                      //  読みだすサイズの設定
            if ( remain < rdsz ) rdsz = remain ;
                                                      //  ファイルから読みだす
            if ( (rdsize = fread( pctrl->buftbl[pctrl->apply_loc].ptr,
                                    1, rdsz, pFile )) != rdsz )
            {
				WAV_playStop() ;
			    error = CANT_LOAD ;
                goto FILEFIN_3 ;
            }

   //  次回のアプリケーション位置を設定し、次々回のアプリケーション位置を算出
            pctrl->apply_loc = nextloc ;
            if ( (nextloc += 4) == pctrl->sum )    nextloc = 0 ;

            //  サンプリングデータの残りサイズの算出
            remain -= rdsize ;
        }
    } ;                                              //  while文の終了

    //  後処理
FILEFIN_3 :;
    fclose( pFile ) ;
FILEFIN_2 :;
//	TL_free( pctrl ) ;
FILEFIN_1 :;
//	TL_free( pring ) ;
//	TL_freeLot( lot ) ;

    return error ;
}


//  temp1 データの情報のみを得る

int  readWavDataInfo1( int *fq, int *bit, int *kd, int *sz )
{
	int st ;
	return	readInfo( sndBufFile1, fq, bit, kd, sz, &st ) ;
}

//  temp2 データの情報のみを得る

int  readWavDataInfo( int *fq, int *bit, int *kd, int *sz )
{
	int st ;
	return	readInfo( sndBufFile2, fq, bit, kd, sz, &st ) ;
}

//  temp2 データを読み込み

#define   readWavDataBind  (100*4096)          //  バインドの大きさ

static FILE  *readFile ;                       //  ファイルポインタ
static char  *readRing ;                       //  リングバッファポインタ
static int   readFreq ;                        //  サンプリング周波数
static int   readBitno ;                       //  サンプリングビット数
static int   readKind ;                        //  データ種別
static int   readPcmsz ;                       //  PCMデータサイズ

static int   readBCount ;                  //  バインドカウンター
static int   readFileData ;                //  すでに読み込んだファイルデータ

int  readWavData_init( int *fq, int *bit, int *kd, int *sz )
{
    int   ret ;                         //  戻り値
    int   pcmstart ;                    //  PCMデータ相対開始位置
    int   rdsz ;                        //  読み込むデータサイズ
    int   rdsize ;                      //  読み込まれたデータサイズ
    int   error ;
    int   i, x ;

	error = NOERR ;

    //  リングバッファの領域の確保を行う
    if ( (readRing = TL_malloc( 2 * readWavDataBind + 256 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }

    //  ファイルをオープンする
    if( (readFile = fopen( sndBufFile2, "rb" )) == NULL )  //  ファイルオープン
    {
        error = CANT_LOAD ;
        goto FILEFIN_2 ;
    }

    //  リングバッファを使用してファイルの情報を取得する
    rdsz = 0 ;
    do
    {
        rdsz += 50 ;
        //  ファイルポインタをWAVEデータの先頭に位置づける
        ret = fseek( readFile, 0, SEEK_SET ) ;
        if ( ret != 0 )
        {
	        error = CANT_LOAD ;
            goto FILEFIN_3 ;
        }
        rdsize = fread( readRing, 1, rdsz, readFile ) ;

        if ( rdsize != rdsz )
        {
	        error = CANT_LOAD ;
            goto FILEFIN_3 ;
        }
        ret = WAV_getWaveInfo( readRing, rdsz, 
        	&readFreq, &readBitno, &readKind, &readPcmsz, &pcmstart) ;
	} while( ret == 23 ) ;

    //  ファイルポインタをPCMデータの先頭に位置づける
    ret = fseek( readFile, pcmstart, SEEK_SET ) ;
    if ( ret != 0 )
    {
        error = CANT_LOAD ;
        goto FILEFIN_3 ;
    }

	if( readBitno == 16 )
		x = 0 ;
	else
		x = 0x80808080 ;
	for( i=0 ; i<(2 * readWavDataBind) ; i += 4 )
	{
		DWORD( readRing + i ) = x ;
	}

 	fread( readRing, 1, readWavDataBind, readFile ) ;

	if( readBitno != 16 && readBitno != 8 )
	{
		error = ILLIGAL_DATA ;
        goto FILEFIN_3 ;
    }
	if( readKind != 2 && readKind != 1 )
	{
		error = ILLIGAL_DATA ;
        goto FILEFIN_3 ;
    }

	readBCount = 0 ;                 //  バインドカウンター

	// すでに読み込んだファイルデータ
	readFileData = ( readWavDataBind / ( (readBitno/8) * readKind ) ) ;

	*fq = readFreq ;
	*bit = readBitno ;
	*kd = readKind ;
	*sz = readPcmsz ;

	return NOERR ;

    //  後処理
FILEFIN_3 :;
    fclose( readFile ) ;
FILEFIN_2 :;
FILEFIN_1 :;
    TL_free( readRing ) ;

    return error ;
}

int  readWavData( int point, int *left, int *right )
{
	int bindstart ;
	int rdsize ;
	int rp ;
	int i ;
	int x ;

	if( readBitno == 16 && readKind == 2 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind ;

//		if( point >= readFileData )
		while( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind ;

	        rdsize = fread(readRing + bindstart, 1, readWavDataBind, readFile);

	        if( rdsize < readWavDataBind )
    	    {
        		for( i=(rdsize >> 1) ; i<(readWavDataBind >> 1) ; i++ )
        			WORD( readRing + bindstart + i*2 ) = 0 ;
	        }

			readFileData += ( readWavDataBind >> 2 ) ;
		}

		rp = point - ( readBCount*readWavDataBind >> 2 ) ;
		if( rp >= ( readWavDataBind >> 2 ) )
			rp = ( readWavDataBind >> 2 ) - 1 ;
		if( rp < ( - readWavDataBind >> 2 ) )
			rp = ( - readWavDataBind >> 2 ) ;
		rp = rp + ( bindstart >> 2 ) ;
//		if( rp < 0 )
//			rp = ( readWavDataBind >> 2 )*2 + rp ;
		if( rp < 0 )
			rp = ( readWavDataBind >> 1 ) + rp ;

		if( rp < 0 )
			rp = 0 ;
//		if( rp >= ( readWavDataBind >> 2 )*2 )
//			rp = ( readWavDataBind >> 2 )*2 - 1 ;
		if( rp >= ( readWavDataBind >> 1 ) )
			rp = ( readWavDataBind >> 1 ) - 1 ;

		*left = WORD( readRing + (rp << 2) ) ;
		if( (*left) & 0x8000 )
			*left |= 0xffff0000 ;
		*right = WORD( readRing + (rp << 2) + 2 ) ;
		if( (*right) & 0x8000 )
			*right |= 0xffff0000 ;
		return NOERR ;
	}
	else if( readBitno == 16 && readKind == 1 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind ;

//		if( point >= readFileData )
		while( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind ;

	        rdsize = fread(readRing + bindstart, 1, readWavDataBind, readFile);

	        if( rdsize < readWavDataBind )
    	    {
        		for( i=(rdsize >> 1) ; i<(readWavDataBind >> 1) ; i++ )
        			WORD( readRing + bindstart + i*2 ) = 0 ;
	        }

			readFileData += ( readWavDataBind >> 1 ) ;
		}

		rp = point - ( readBCount*readWavDataBind >> 1 ) ;
		if( rp >= ( readWavDataBind >> 1 ) )
			rp = ( readWavDataBind >> 1 ) - 1 ;
		if( rp < ( - readWavDataBind >> 1 ) )
			rp = ( - readWavDataBind >> 1 ) ;
		rp = rp + ( bindstart >> 1 ) ;
//		if( rp < 0 )
//			rp = ( readWavDataBind >> 1 )*2 + rp ;
		if( rp < 0 )
			rp = readWavDataBind + rp ;

		if( rp < 0 )
			rp = 0 ;
//		if( rp >= ( readWavDataBind >> 1 )*2 )
//			rp = ( readWavDataBind >> 1 )*2 - 1 ;
		if( rp >= readWavDataBind )
			rp = readWavDataBind - 1 ;

		*left = WORD( readRing + (rp << 1) ) ;
		if( (*left) & 0x8000 )
			*left |= 0xffff0000 ;
		*right = 0 ;
		return NOERR ;
	}
	else if( readBitno == 8 && readKind == 2 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind ;

//		if( point >= readFileData )
		while( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind ;

	        rdsize = fread(readRing + bindstart, 1, readWavDataBind, readFile);

	        if( rdsize < readWavDataBind )
    	    {
        		for( i=rdsize ; i<readWavDataBind ; i++ )
        			BYTE( readRing + bindstart + i ) = 0x80 ;
	        }

			readFileData += ( readWavDataBind >> 1 ) ;
		}

		rp = point - ( readBCount*readWavDataBind >> 1 ) ;
		if( rp >= ( readWavDataBind >> 1 ) )
			rp = ( readWavDataBind >> 1 ) - 1 ;
		if( rp < ( - readWavDataBind >> 1 ) )
			rp = ( - readWavDataBind >> 1 ) ;
		rp = rp + ( bindstart >> 1 ) ;
//		if( rp < 0 )
//			rp = ( readWavDataBind >> 1 )*2 + rp ;
		if( rp < 0 )
			rp = readWavDataBind + rp ;

		if( rp < 0 )
			rp = 0 ;
//		if( rp >= ( readWavDataBind >> 1 )*2 )
//			rp = ( readWavDataBind >> 1 )*2 - 1 ;
		if( rp >= readWavDataBind )
			rp = readWavDataBind - 1 ;

		x = BYTE( readRing + (rp << 1) ) ;
		*left = ( x - 128 ) << 8 ;
		x = BYTE( readRing + (rp << 1) + 1 ) ;
		*right = ( x - 128 ) << 8 ;
		return NOERR ;
	}
	else if( readBitno == 8 && readKind == 1 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind ;

//		if( point >= readFileData )
		while( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind ;

	        rdsize = fread(readRing + bindstart, 1, readWavDataBind, readFile);

	        if( rdsize < readWavDataBind )
    	    {
        		for( i=rdsize ; i<readWavDataBind ; i++ )
        			BYTE( readRing + bindstart + i ) = 0x80 ;
	        }

			readFileData += readWavDataBind ;
		}

		rp = point - readBCount*readWavDataBind ;
		if( rp >= readWavDataBind )
			rp = readWavDataBind - 1 ;
		if( rp < ( - readWavDataBind ) )
			rp = ( - readWavDataBind ) ;
		rp = rp + bindstart ;
		if( rp < 0 )
			rp = readWavDataBind * 2 + rp ;

		if( rp < 0 )
			rp = 0 ;
		if( rp >= readWavDataBind*2 )
			rp = readWavDataBind*2 - 1 ;

		x = BYTE( readRing + rp ) ;
		*left = ( x - 128 ) << 8 ;
		*right = 0 ;
		return NOERR ;
	}

	return NOERR ;
}

int  readWavData_end()
{
    fclose( readFile ) ;
    TL_free( readRing ) ;

    return NOERR ;
}

//  temp1 データに書き込み

#define   writeWavDataBind  (100*4096)          //  バインドの大きさ

static FILE  *writeFile ;                       //  ファイルポインタ
static char  *writeRing ;                       //  リングバッファポインタ
static int   writeFreq ;                        //  サンプリング周波数
static int   writeBitno ;                       //  サンプリングビット数
static int   writeKind ;                        //  データ種別
static int   writePcmsz ;                       //  PCMデータサイズ

static int   writeBCount ;                  //  バインド内カウンター
static int   writeFileData ;                //  すでに書き込んだファイルデータ

int  writeWavData_init( int fq, int bit, int kd, int sz )
{
	char head[256] ;

    int   pcmstart ;                    //  PCMデータ相対開始位置
    int   error ;

	error = NOERR ;

	writeFreq = fq ;
	writeBitno = bit ;
	writeKind = kd ;
	writePcmsz = sz ;

    //  リングバッファの領域の確保を行う
    if ( (writeRing = TL_malloc( writeWavDataBind + 256 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }

    //  ファイルをオープンする
    if ( (writeFile = fopen( sndBufFile1, "wb" )) == NULL )  //  ファイル作成
    {
        error = CANT_LOAD ;
        goto FILEFIN_2 ;
    }

    //  WAVEファイルの情報を作成しファイルに書きだす
    WAV_setWaveInfo_2( head, writeFreq, writeBitno,
    							writeKind, writePcmsz, &pcmstart ) ;
    if ( fwrite( head, 1, 44, writeFile) != 44 )
    {
		error = CANT_SAVE ;
        goto FILEFIN_3 ;
    }

	writeBCount = 0 ;                 //  バインドカウンター
	writeFileData = 0 ;               // すでに読み込んだファイルデータ
	return NOERR ;

    //  後処理
FILEFIN_3 :;
    fclose( writeFile ) ;
FILEFIN_2 :;
FILEFIN_1 :;
    TL_free( writeRing ) ;

    return error ;
}

int  writeWavData( int left, int right )
{
	int wrtsize ;
	int x, y ;

	if( left > 32767 )left = 32767 ;
	if( left < -32768 )left = -32768 ;
	if( right > 32767 )right = 32767 ;
	if( right < -32768 )right = -32768 ;

	if( writeBitno == 16 && writeKind == 2 )
	{
		DWORD( writeRing + (writeBCount * 4) )
			 = (left & 0x0000ffff) + (right << 16) ;
		writeBCount++ ;

		if( (writeBCount * 4) >= writeWavDataBind )
		{
			wrtsize = fwrite( writeRing, 1, writeWavDataBind, writeFile) ;
			writeFileData += ( wrtsize / 4 ) ;
			writeBCount = 0 ;
			if ( wrtsize != writeWavDataBind )
			{
				writeWavData_end() ;
		    	return CANT_SAVE ;
			}
		}
		return NOERR ;
	}
	else if( writeBitno == 16 && writeKind == 1 )
	{
		WORD( writeRing + (writeBCount * 2) ) = left ;
		writeBCount++ ;

		if( (writeBCount * 2) >= writeWavDataBind )
		{
			wrtsize = fwrite( writeRing, 1, writeWavDataBind, writeFile) ;
			writeFileData += ( wrtsize / 2 ) ;
			writeBCount = 0 ;
			if ( wrtsize != writeWavDataBind )
			{
				writeWavData_end() ;
		    	return CANT_SAVE ;
			}
		}
		return NOERR ;
	}
	else if( writeBitno == 8 && writeKind == 2 )
	{
		x = (left >> 8) + 128 ;
		if( x < 0 )x = 0 ;
		if( x > 255 )x = 255 ;
		y = (right >> 8) + 128 ;
		if( y < 0 )y = 0 ;
		if( y > 255 )y = 255 ;
		WORD( writeRing + (writeBCount * 2) )
			 = (x & 0x00ff) + ((y << 8) & 0xff00) ;
		writeBCount++ ;

		if( (writeBCount * 2) >= writeWavDataBind )
		{
			wrtsize = fwrite( writeRing, 1, writeWavDataBind, writeFile) ;
			writeFileData += ( wrtsize / 2 ) ;
			writeBCount = 0 ;
			if ( wrtsize != writeWavDataBind )
			{
				writeWavData_end() ;
		    	return CANT_SAVE ;
			}
		}
		return NOERR ;
	}
	else if( writeBitno == 8 && writeKind == 1 )
	{
		x = (left >> 8) + 128 ;
		if( x < 0 )x = 0 ;
		if( x > 255 )x = 255 ;
		BYTE( writeRing + writeBCount ) = (x & 0x00ff) ;
		writeBCount++ ;

		if( writeBCount >= writeWavDataBind )
		{
			wrtsize = fwrite( writeRing, 1, writeWavDataBind, writeFile) ;
			writeFileData += wrtsize ;
			writeBCount = 0 ;
			if ( wrtsize != writeWavDataBind )
			{
				writeWavData_end() ;
		    	return CANT_SAVE ;
			}
		}
		return NOERR ;
	}

	return NOERR ;
}

int  writeWavData_end()
{
	char head[256] ;
	int wrtsize ;
	int pcmstart ;
	int error ;

	error = NOERR ;

	if( writeBitno == 16 && writeKind == 2 )
	{
		if( writeBCount )
		{
			wrtsize = fwrite( writeRing, 1, (writeBCount * 4), writeFile) ;
			writeFileData += ( wrtsize / 4 ) ;
			writeBCount = 0 ;
			if(	wrtsize != (writeBCount * 4) )
				error = CANT_SAVE ;
		}

		fseek( writeFile, 0, SEEK_SET ) ;
    	WAV_setWaveInfo_2( head, writeFreq, writeBitno,
    							writeKind, (writeFileData *4), &pcmstart ) ;
	    //  WAVEファイルの情報を作成しファイルに書きだす
    	if ( (wrtsize = fwrite( head, 1, 44, writeFile)) != 44 )
	    {
			error = CANT_SAVE ;
	    }
	}
	else if( writeBitno == 16 && writeKind == 1 )
	{
		if( writeBCount )
		{
			wrtsize = fwrite( writeRing, 1, (writeBCount * 2), writeFile) ;
			writeFileData += ( wrtsize / 2 ) ;
			writeBCount = 0 ;
			if(	wrtsize != (writeBCount * 2) )
				error = CANT_SAVE ;
		}

		fseek( writeFile, 0, SEEK_SET ) ;
    	WAV_setWaveInfo_2( head, writeFreq, writeBitno,
    							writeKind, (writeFileData *2), &pcmstart ) ;
	    //  WAVEファイルの情報を作成しファイルに書きだす
    	if ( (wrtsize = fwrite( head, 1, 44, writeFile)) != 44 )
	    {
			error = CANT_SAVE ;
	    }
	}
	else if( writeBitno == 8 && writeKind == 2 )
	{
		if( writeBCount )
		{
			wrtsize = fwrite( writeRing, 1, (writeBCount * 2), writeFile) ;
			writeFileData += ( wrtsize / 2 ) ;
			writeBCount = 0 ;
			if(	wrtsize != (writeBCount * 2) )
				error = CANT_SAVE ;
		}

		fseek( writeFile, 0, SEEK_SET ) ;
    	WAV_setWaveInfo_2( head, writeFreq, writeBitno,
    							writeKind, (writeFileData *2), &pcmstart ) ;
	    //  WAVEファイルの情報を作成しファイルに書きだす
    	if ( (wrtsize = fwrite( head, 1, 44, writeFile)) != 44 )
	    {
			error = CANT_SAVE ;
	    }
	}
	else if( writeBitno == 8 && writeKind == 1 )
	{
		if( writeBCount )
		{
			wrtsize = fwrite( writeRing, 1, writeBCount, writeFile) ;
			writeFileData += wrtsize ;
			writeBCount = 0 ;
			if(	wrtsize != writeBCount )
				error = CANT_SAVE ;
		}

		fseek( writeFile, 0, SEEK_SET ) ;
    	WAV_setWaveInfo_2( head, writeFreq, writeBitno,
    							writeKind, writeFileData, &pcmstart ) ;
	    //  WAVEファイルの情報を作成しファイルに書きだす
    	if ( (wrtsize = fwrite( head, 1, 44, writeFile)) != 44 )
	    {
			error = CANT_SAVE ;
	    }
	}

    fclose( writeFile ) ;
    TL_free( writeRing ) ;

    return error ;
}

/* name1のwavデータをname2に送る */

#define   wavFileTransBuf  (100*4096)          //  バッファの大きさ

int wavFileTrans( char *name1, char *name2 )
{
	FILE *fp1 ;	    /* ファイルのストリーム情報を記憶する変数のポインタ */
	FILE *fp2 ;	    /* ファイルのストリーム情報を記憶する変数のポインタ */
	char *buffer ;
	int pcmstart ;
	int i, total ;
	int ret ;
	int fq, bit, kd, sz, start ;

	ret = NOERR ;

	if( (ret = readInfo( name1, &fq, &bit, &kd, &sz, &start )) != NOERR )
		return ret ;

    //  バッファの領域の確保を行う
    if ( (buffer = TL_malloc( wavFileTransBuf + 256 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }

	if( ( fp1 = fopen( name1, "rb" ) ) == NULL )	/* ファイルオープン */
	{
		ret = CANT_LOAD ;  	  /* オープンできなかったらエラーを返す */
		goto END01 ;
	}

    if( fseek( fp1, start, SEEK_SET ) )
	{
		ret = CANT_LOAD ;  	  /* エラーを返す */
		goto END02 ;
	}

	if( ( fp2 = fopen( name2, "wb" ) ) == NULL )	/* ファイルオープン */
	{
		ret = CANT_SAVE ;  	  /* オープンできなかったらエラーを返す */
		goto END02 ;
	}

    //  WAVEファイルの情報を作成しファイルに書きだす
    WAV_setWaveInfo_2( buffer, fq, bit, kd, sz, &pcmstart ) ;
    if( fwrite( buffer, 1, 44, fp2) != 44 )
    {
		ret = CANT_SAVE ;
		goto END03 ;
    }

	total = 0 ;

	for( i=0 ; i<sz ; i=i+wavFileTransBuf )
	{
		int size ;

		size = fread( buffer, 1, wavFileTransBuf, fp1 ) ;

		if( size )
		{
			if( fwrite( buffer, size, 1, fp2 ) < 1 )
			{
				ret = CANT_SAVE ;		/* エラーを返す */
				goto END03 ;
			}
			else
			{
				total += size ;
			}
		}
		else
		{
			break ;
		}
	}

END03: ;

    //  WAVEファイルの情報を作成しファイルに書きだす
    if( fseek( fp2, 0, SEEK_SET ) )total -= 4*4096 ; // 16kデータを失うかも
    if( total < 0 )total = 0 ;
    WAV_setWaveInfo_2( buffer, fq, bit, kd, total, &pcmstart ) ;
    if ( fwrite( buffer, 1, 44, fp2) != 44 )
		ret = CANT_SAVE ;

	fclose( fp2 ) ;	  		/* クローズする */
END02: ;
	fclose( fp1 ) ;	  		/* クローズする */
END01: ;
    TL_free( buffer ) ;
END00: ;
	return ret ;
}

/* データの情報を得る */

static int readInfo( char *name, int *fq, int *bit, int *kd, int *sz, int *st )
{
    FILE  *pFile ;                      //  ファイルポインタ

	char head[512] ;

    int   ret ;                         //  戻り値
    int   freq = 0 ;                    //  サンプリング周波数
    int   bitno = 0 ;                   //  サンプリングビット数
    int   kind = 0 ;                    //  データ種別
    int   pcmsz = 0 ;                   //  PCMデータサイズ
    int   pcmstart = 44 ;               //  PCMデータ相対開始位置
    int   rdsz ;                        //  読み込むデータサイズ
    int   rdsize ;                      //  読み込まれたデータサイズ
    int   error ;

	error = NOERR ;

    //  再生ファイルをオープンする
    if ( (pFile = fopen( name, "rb" )) == NULL )  //  ファイルオープン
    {
        error = NO_DATA ;
        goto FILEFIN_2 ;
    }

    //  ファイルの情報を取得する
	for( rdsz = 50 ; rdsz <= 500 ; rdsz += 50 )
    {
        //  ファイルポインタをWAVEデータの先頭に位置づける
        ret = fseek( pFile, 0, SEEK_SET ) ;
        if ( ret != 0 )
        {
	        error = CANT_LOAD ;
            goto FILEFIN_3 ;
        }
        rdsize = fread( head, 1, rdsz, pFile ) ;

        if ( rdsize != rdsz )
        {
	        error = CANT_LOAD ;
            goto FILEFIN_3 ;
        }
        ret = WAV_getWaveInfo( head, rdsz, &freq, &bitno, &kind,
                                                     &pcmsz, &pcmstart) ;
		if( ret != 23 )
			break ;

	}

	if( ret == 23 )
    {
        error = ILLIGAL_DATA ;
        goto FILEFIN_3 ;
    }

    //  後処理
FILEFIN_3 :;
    fclose( pFile ) ;
FILEFIN_2 :;
FILEFIN_1 :;

	*fq = freq ;
	*bit = bitno ;
	*kd = kind ;
	*sz = pcmsz ;
	*st = pcmstart ;

	return error ;
}

typedef struct
{
		char riffld[4] ;
		int riffSize ;
		char formType[4] ;

		char fmtId[4] ;
		int fmtSize ;
		short int waveFormatType ;
		short int channel ;
		int samplesPerSec ;
		int bytesPerSec ;
		short int blockSize ;
		short int bitesPerSample ;

		char dataId[4] ;
		int dataSize ;

} WAVECHUNK ;

//int WAV_setWaveInfo( char *buf, int freq, int bitno, int kind,
//                     int pcmsz, int *pcmst ) ;
//  にバグあるため､代わりの関数

int WAV_setWaveInfo_2( char *buf,
					   int fq, int bit, int kd, int sz, int *pcmst )
{
	WAVECHUNK *wave ;

	wave = (WAVECHUNK *)buf ;

	DWORD( wave->riffld ) = DWORD( "RIFF" ) ;
	DWORD( wave->formType ) = DWORD( "WAVE" ) ;
	DWORD( wave->fmtId ) = DWORD( "fmt " ) ;
	DWORD( wave->dataId ) = DWORD( "data" ) ;
	wave->riffSize = sz + 36 ;
	wave->fmtSize = 16 ;
	wave->dataSize = sz ;

	wave->waveFormatType = 1 ;
	wave->channel = kd ;
	wave->samplesPerSec = fq ;
	wave->bytesPerSec = bit * kd / 8 * fq ;
	wave->blockSize = bit * kd / 8 ;
	wave->bitesPerSample = bit ;

	*pcmst = 44 ;

	return NOERR ;
}

