//	録音 & 特殊な読み込みルーチン

#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"

/* mix */
int	mixDialogId = -1 ;
int	mixMesId[30] = -1 ;
int	mixSubDialogId = -1 ;
int	mixDiskVolumeId = -1 ;
int	mixMemoryVolumeId = -1 ;
int	mixDiskNumId = -1 ;
int	mixMemoryNumId = -1 ;
int	mixOkBtnId = -1 ;
int	mixCanBtnId = -1 ;

/* rec */
int	recDialogId = -1 ;
int	recMesId[13] = -1 ;
int	recOkBtnId = -1 ;
int	recPlayBtnId = -1 ;
int	recUndoBtnId = -1 ;
int	recCanBtnId = -1 ;
int	recSubDialogId = -1 ;
int	recLineVolumeId = -1 ;
int	recCdVolumeId = -1 ;
int	recMicVolumeId = -1 ;
int	recLineNumId = -1 ;
int	recCdNumId = -1 ;
int	recMicNumId = -1 ;
int	recTimeNumId = -1 ;
int	recFreqBtnId[3] = -1 ;
int	recFreqMesId[3] = -1 ;
int	recChanBtnId[2] = -1 ;
int	recChanMesId[2] = -1 ;
int	recBitBtnId[2] = -1 ;
int	recBitMesId[2] = -1 ;
int	recSub2DialogId = -1 ;
int	recMessageId = -1 ;

extern char sndBufFile1[] ; // これを extern char *snd…とするとえらー
//extern char sndBufFile2[] ; // これを extern char *snd…とするとえらー

/*	MIX */

static int mixFlag ;

int	sndMix( char *name )
{
	int var, min, max, delta, ptColumn ;
	int vl1, vl2 ;
	int ret ;

	MMI_SendMessage( mixDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( mixDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( mixDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( mixDialogId, MM_DETACH, 0 ) ;

	if( mixFlag == TRUE )
	{
		SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */

		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( mixMemoryNumId, MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
		vl1 = var * 256 / 100 ;
		MMI_SendMessage( mixDiskNumId, MM_GETNUMBOX, 5,
							&var, &min, &max, &delta, &ptColumn ) ;
		vl2 = var * 256 / 100 ;

		if( get_file_kakucho( name ) == DWORD( ".WAV" ) )
			ret = wavMixLoad( name, vl1, vl2 ) ;

		if( get_file_kakucho( name ) == DWORD( ".SND" ) )
			ret = sndMixLoad( name, vl1, vl2 ) ;

END_00: ;
		SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

		if( ret )
			errorCheck( ret ) ;

		MMI_FlushEvnt() ;	/* イベントをフラッシュ */
	}

	return NOERR ;
}

/* 各種ボリューム設定 */
int	mixVolumeSet(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 == mixDiskVolumeId )	/* ディスクmixVol. */
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( mixDiskNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( mixDiskNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( mixDiskNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == mixDiskNumId )	/* ディスクmixNum. */
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( mixDiskVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( mixDiskVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( mixDiskVolumeId, MM_SHOW, 0 ) ;
	}

	if( kobj == mixMemoryVolumeId )	/* メモリmixVol. */
	{
		MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( mixMemoryNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( mixMemoryNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( mixMemoryNumId, MM_SHOW, 0 ) ;
	}

	if( kobj == mixMemoryNumId )	/* メモリmixNum. */
	{
		MMI_SendMessage( kobj, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( mixMemoryVolumeId, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;
		MMI_SendMessage( mixMemoryVolumeId, MM_SETSCROLL, 5,
										var2, min, max, len, page ) ;
		MMI_SendMessage( mixMemoryVolumeId, MM_SHOW, 0 ) ;
	}

	return NOERR ;
}

/* 実行, 取消 */
int	mixOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	if( kobj == mixOkBtnId )
		mixFlag = TRUE ;
	else
		mixFlag = FALSE ;
	MMI_SetHaltFlag( TRUE ) ;

	return NOERR ;
}


/*	REC */

static int recFreqMode = 0 ;
static int recChanMode = 0 ;
static int recBitMode  = 0 ;
static int recCapacity ;

int	sndRec()
{
	int var, min, max, delta, ptColumn ;
	int i ;

    WAV_getCapability( &recCapacity, 22050 ) ; 
    if ( recCapacity & WAV_CAP_16PCM_EXIST )
    {                              //  16ビットPCMによるサンプリング
		MMI_SendMessage( recMessageId, MM_SETMSG, 1,
			"録音中にマウス左右ボタンを押すと強制終了します｡" ) ;

		MTL_resetAtrObj( recFreqBtnId[0], (~MS_DSPONLYL40) ) ;

		MTL_resetAtrObj( recChanBtnId[0], (~MS_DSPONLYL40) ) ;

		MTL_resetAtrObj( recBitBtnId[0], (~MS_DSPONLYL40) ) ;
    }
    else
    {                             //  内蔵PCMによるサンプリング
		MMI_SendMessage( recMessageId, MM_SETMSG, 1,
			"本機では22050Hz以下,8bit,ﾓﾉﾗﾙの録音しかできません｡" ) ;

		MTL_resetAtrObj( recFreqBtnId[0], (~MS_DSPONLYL40) ) ;
		MTL_setAtrObj( recFreqBtnId[0], MS_INACTIVEL40 ) ;

		MTL_resetAtrObj( recChanBtnId[0], (~MS_DSPONLYL40) ) ;
		MTL_setAtrObj( recChanBtnId[0], MS_INACTIVEL40 ) ;

		MTL_resetAtrObj( recBitBtnId[0], (~MS_DSPONLYL40) ) ;
		MTL_setAtrObj( recBitBtnId[0], MS_INACTIVEL40 ) ;

		if( recFreqMode == 0 )recFreqMode = 1 ;
		recChanMode = 1 ;
		recBitMode = 1 ;
    }

	/* ボタンセット */
	for( i=0 ; i<3 ; i++ )
		MTL_resetFlagObj( recFreqBtnId[i], (~(MS_UNSELECT | MS_TOGGLE)) ) ;
	MTL_setFlagObj( recFreqBtnId[recFreqMode], (MS_UNSELECT | MS_TOGGLE) ) ;

	for( i=0 ; i<2 ; i++ )
		MTL_resetFlagObj( recChanBtnId[i], (~(MS_UNSELECT | MS_TOGGLE)) ) ;
	MTL_setFlagObj( recChanBtnId[recChanMode], (MS_UNSELECT | MS_TOGGLE) ) ;

	for( i=0 ; i<2 ; i++ )
		MTL_resetFlagObj( recBitBtnId[i], (~(MS_UNSELECT | MS_TOGGLE)) ) ;
	MTL_setFlagObj( recBitBtnId[recBitMode], (MS_UNSELECT | MS_TOGGLE) ) ;


	/* ボリュームセット */
	SND_elevol_mute( 0x00000000 ) ;
	MMI_SendMessage( recLineNumId, MM_GETNUMBOX, 5, /* Line Volune set */
							&var, &min, &max, &delta, &ptColumn ) ;
	if( var )
		SND_elevol_set( 0, var, var ) ;

	MMI_SendMessage( recCdNumId, MM_GETNUMBOX, 5, /* CD Volune set */
							&var, &min, &max, &delta, &ptColumn ) ;
	if( var )
		SND_elevol_set( 1, var, var ) ;

	MMI_SendMessage( recMicNumId, MM_GETNUMBOX, 5, /* Mic Volune set */
							&var, &min, &max, &delta, &ptColumn ) ;
	if( var )
		SND_elevol_set( 2, var, var ) ;

	MMI_SendMessage( recDialogId, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	MMI_SendMessage( recDialogId, MM_SHOW, 0 ) ;	/* 全体を見せる */

	MMI_ExecSystem() ;		/* Dialog表示へ･･･イベントループ */

	MMI_SendMessage( recDialogId, MM_ERASE, 0 ) ;
	MMI_SendMessage( recDialogId, MM_DETACH, 0 ) ;

	SND_elevol_mute( 0x00000000 ) ;

	return NOERR ;
}

/* 実行 */
int	recOkchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int ret ;

	if( trigger & MS_EVMOSONL40 )
	{
		temp1_to_temp2() ;		/* temp1をtemp2へ */

		SetMouse16( 81, 0xf, 0x8 ) ;	/* マウスカーソルをウエイト表示 */
//		setMsgColor( recMesId[0], EXE_COLOR ) ;

		ret = sndRecExec() ;

		tempFileCount++ ;		/* 現在作られてるテンポラリファイルの数 */
		if( tempFileCount > 2 )
			tempFileCount = 2 ;

		setMsgColor( recMesId[0], MOJI_COLOR ) ;
		SetMouse16( 80, 0xf, 0x8 ) ;	/* マウスカーソルを元に */

		if( ret )
			errorCheck( ret ) ;

		MMI_FlushEvnt() ;	/* イベントをフラッシュ */
	}
	return NOERR ;
}

/* 取消 */
int	recCanchk(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	MMI_SetHaltFlag( TRUE ) ;
	return NOERR ;
}

/* 再生 */
int	recPlay(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	static int s = 0 ;
	static int lev = 0 ;

	if( trigger & MS_EVMOSONL40 )	/* マウスONで消音 */
	{
		if( lev == 0 )
		{
			lev = 1 ;
			SND_get_elevol_mute( &s ) ;
			SND_elevol_mute( 0 ) ;
		}
	}

	if( trigger & MS_EVDRAGOUTL40 )	/* オブジェクト外で音の復帰 */
	{
		if( lev == 1 )
		{
			lev = 0 ;
			SND_elevol_mute( s ) ;
		}
	}

	if( trigger & MS_EVMOSOFFL40 )	/* マウスOFFで再生開始 */
	{
		if( lev == 0 )
		{
			lev = 1 ;
			SND_get_elevol_mute( &s ) ;
			SND_elevol_mute( 0 ) ;
		}

		setMsgColor( recMesId[1], EXE_COLOR ) ;

		sndPlay() ;

		setMsgColor( recMesId[1], MOJI_COLOR ) ;

		SND_elevol_mute( s ) ;
		lev = 0 ;
	}

	return NOERR ;
}

/* アンドゥ */
int	recUndo(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	setMsgColor( recMesId[2], EXE_COLOR ) ;

	unDo() ;

	setMsgColor( recMesId[2], MOJI_COLOR ) ;

	MMI_FlushEvnt() ;	/* イベントをフラッシュ */

	return NOERR ;
}

/* 各種ボリュームの設定 */
int	recVolumeSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int	var, min, max, len, page, s ;
	int	var2, min2, max2, delta2, ptColumn2 ;

	MMI_SendMessage( kobj, MM_GETSCROLL, 5,
										&var, &min, &max, &len, &page ) ;

	if( kobj == recLineVolumeId )	/* ライン入力 */
	{
		MMI_SendMessage( recLineNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( recLineNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( recLineNumId, MM_SHOW, 0 ) ;
		SND_elevol_set( 0, var, var );		/* line volume set */
		if( var == 0 )
		{
			SND_get_elevol_mute( &s ) ;
			SND_elevol_mute( s & 0xfffffff3 ) ;
		}
	}

	if( kobj == recCdVolumeId )		/* CD */
	{
		MMI_SendMessage( recCdNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( recCdNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( recCdNumId, MM_SHOW, 0 ) ;
		SND_elevol_set( 1, var, var );		/* cd volume set */
		if( var == 0 )
		{
			SND_get_elevol_mute( &s ) ;
			SND_elevol_mute( s & 0xffffffcf ) ;
		}
	}

	if( kobj == recMicVolumeId )	/* マイク */
	{
		MMI_SendMessage( recMicNumId, MM_GETNUMBOX, 5,
							&var2, &min2, &max2, &delta2, &ptColumn2 ) ;
		MMI_SendMessage( recMicNumId, MM_SETNUMBOX, 5,
							var, min2, max2, delta2, ptColumn2 ) ;
		MMI_SendMessage( recMicNumId, MM_SHOW, 0 ) ;
		SND_elevol_set( 2, var, var );		/* mic volume set */
		if( var == 0 )
		{
			SND_get_elevol_mute( &s ) ;
			SND_elevol_mute( s & 0xffffffbf ) ;
		}
	}

	return NOERR ;
}

/* 録音時間 */
int	recTimeSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	return NOERR ;
}

/*	initDataIWVREC:recFreqBtnId[0]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIWVREC:recFreqBtnId[1]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIWVREC:recFreqBtnId[2]:MJ_TICONL40の呼び出し関数	*/
int	recFreqSet(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 == recFreqBtnId[i] )
		{
			MTL_setFlagObj( recFreqBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( recFreqBtnId[recFreqMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( recFreqBtnId[recFreqMode], MM_SHOW, 0 ) ;
			recFreqMode = i ;
		}
	}
	return NOERR ;
}

/*	initDataIWVREC:recChanBtnId[0]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIWVREC:recChanBtnId[1]:MJ_TICONL40の呼び出し関数	*/
int	recChanSet(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 == recChanBtnId[i] )
		{
			MTL_setFlagObj( recChanBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( recChanBtnId[recChanMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( recChanBtnId[recChanMode], MM_SHOW, 0 ) ;
			recChanMode = i ;
		}
	}
	return NOERR ;
}

/*	initDataIWVREC:recBitBtnId[0]:MJ_TICONL40の呼び出し関数	*/
/*	initDataIWVREC:recBitBtnId[1]:MJ_TICONL40の呼び出し関数	*/
int	recBitSet(kobj, messId, argc, pev, trigger)
int		kobj ;
int		messId ;
int		argc ;
EVENT	*pev ;
int		trigger ;
{
	int i ;

	for( i=0 ; i<4 ; i++ )
	{
		if( kobj == recBitBtnId[i] )
		{
			MTL_setFlagObj( recBitBtnId[i], MS_UNSELECT ) ;
			MTL_resetFlagObj( recBitBtnId[recBitMode],
								 (~(MS_UNSELECT | MS_TOGGLE)) ) ;
			MMI_SendMessage( recBitBtnId[recBitMode], MM_SHOW, 0 ) ;
			recBitMode = i ;
		}
	}
	return NOERR ;
}

//  変数定義
static int freq = 44100 ;                    //  サンプリング周波数
static int kind = 2 ;                        //  データ種別（＝モノラル）
static int bitN = 16 ;                      //  サンプリングビット数
static int pcmSize = 44100 * (16/8) * 10 ;  //  サンプリングデータ長

/* 録音実行ルーチン */
int sndRecExec()
{
	int	var, min, max, delta, ptColumn ;
	int ret ;

	switch( recFreqMode )
	{
	case 0:
		freq = 44100 ;
		break ;
	case 1:
		freq = 22050 ;
		break ;
	case 2:
		freq = 11025 ;
		break ;
	}
	if( recChanMode == 0 )
		kind = 2 ;
	else
		kind = 1 ;
	if( recBitMode == 0 )
		bitN = 16 ;
	else
		bitN = 8 ;

	MMI_SendMessage( recTimeNumId, MM_GETNUMBOX, 5,	/* 録音時間抽出 */
							&var, &min, &max, &delta, &ptColumn ) ;
	pcmSize = freq * (bitN/8) * kind * var / 10 ;

    if ( recCapacity & WAV_CAP_16PCM_EXIST )
    {                              //  16ビットPCMによるサンプリング
		ret = recfile() ;
	}
	else
    {                              //  8ビットPCMによるサンプリング
		ret = recmemory() ;
	}

	return ret ;
}

static int n_count ;

//  同期関数
//  注意：この同期関数のアドレスが０の場合、NULL指定と誤判断されるので、
//        この関数の位置には注意が必要
static void  syncfunc()
{
      n_count ++ ;
      return ;
}

//  直接ファイルへ１６ＫＢ毎にサンプリングデータを書き込む
static int recfile()
{
    FILE  *pFile ;                //  ファイルポインタ
    char  *pring ;                //  リングバッファポインタ
    char  head[256] ;
    struct  buf_ctrl
    {
        int   sum ;
        int   apply_loc ;
        int   system_loc ;
        struct
        {
            char  *ptr ;
            char  reserve[8] ;
        }   buftbl[2] ;
    }   *pctrl ;                 //  リングバッファ管理テーブルポインタ
    int   cap ;                   //  性能情報
    int   ch, x, y ;              //  マウス用変数
    int   pcmstart ;              //  PCMデータ相対開始位置
    int   wrtsz ;                 //  書き込むデータサイズ
    int   wrtsize ;               //  書き込まれたデータサイズ
    int   remain ;                //  残りサンプリングデータサイズ
    int   fl = 0 ;                //  無限ループフラグ
    int   status ;                //  ステータス
    int   nextloc ;               //  次回のアプリケーション位置
    int   error ;
    int   total ;

	error = NOERR ;

    WAV_getCapability( &cap, freq ) ; 
    if ( !( cap & WAV_CAP_16PCM_EXIST ) )
    {
        return 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 ;
    }
*/

// シェル対応のプログラムの場合ワークは,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, "wb" )) == NULL )  //  ファイル作成
    {
		error = CANT_SAVE ;
        goto FILEFIN_2 ;
    }
    //  WAVEファイルの情報を作成しファイルに書きだす
    WAV_setWaveInfo_2( head, freq, bitN, kind, pcmSize, &pcmstart ) ;
    if ( (wrtsize = fwrite( head, 1, 44, pFile)) != 44 )
    {
		error = CANT_SAVE ;
        goto FILEFIN_3 ;
    }
    //  録音前準備
    remain = pcmSize ;                //  残りサンプリングデータサイズ設定
    n_count = 0 ;                     //  カウンタ値のクリア
    nextloc = 4 ;                     //  次回のアプリケーション位置の設定
    wrtsz = 4*4096 ;                  //  一回当たりのファイル書き込みサイズ
	total = 0 ;
    WAV_recPrepare( freq, bitN, kind, NULL, syncfunc ) ;

	setMsgColor( recMesId[0], EXE_COLOR ) ;		// 実行の表示色を変える

    //  録音開始
    WAV_rec( WAV_REC_IMMEDIATE, 0, pcmSize ) ;      //  録音を行う

    //  指定サイズ録音されるまで繰り返す
    while( fl == 0 )
    {
        MOS_rdpos(&ch, &x, &y) ;
        if( ch >= 3 )
        {
			WAV_recStop() ;
            goto FILEFIN_4 ;
        }

        WAV_getStatus( &status ) ;
        if ( !( status & WAV_ST_REC_PROCESS ) )   //  録音処理が終了していれば
            fl++ ;                                  //  flに1設定

    //  リングバッファ４個分サンプリングされていればファイルにデータを書きだす
        if ( n_count >= 4 )
        {
            n_count -= 4 ;                          //  カウンタ値の再設定
                                                    //  書き込むサイズの設定
            if ( remain < wrtsz ) wrtsz = remain ;
                                                    //  ファイルに書きだす
            if ( (wrtsize = fwrite( pctrl->buftbl[pctrl->apply_loc].ptr,
                                      1, wrtsz, pFile)) != wrtsz )
            {
				WAV_recStop( ) ;	// 強制終了
				error = CANT_SAVE ;
                goto FILEFIN_4 ;
            }
            else
            {
            	total += wrtsize ;
            }
   //  次回のアプリケーション位置を設定し、次々回のアプリケーション位置を算出
            pctrl->apply_loc = nextloc ;
            if ( (nextloc += 4) == pctrl->sum )  nextloc = 0 ;

            //  サンプリングデータの残りサイズの算出
            remain -= wrtsize ;
        }
   //  録音処理が終了していれば、残りのデータを全てファイルに書きだす
        else if ( ( fl != 0 ) && ( remain > 0 ) )
        {
			setMsgColor( recMesId[0], MOJI_COLOR ) ;	// 実行の表示色を変える

            if ( (wrtsize = fwrite( pctrl->buftbl[pctrl->apply_loc].ptr,
                                        1, remain, pFile)) != remain )
            {
				WAV_recStop( ) ;	// 強制終了
				error = CANT_SAVE ;
                goto FILEFIN_4 ;
            }
            else
            {
            	total += wrtsize ;
            }
        }
    } ;                                            //  while文の終了

  FILEFIN_4 :;
	if( fseek( pFile, 0, SEEK_SET ) )total -= 4*4096 ;	// 16k失うかも
	if( total < 0 )total = 0 ;
    WAV_setWaveInfo_2( head, freq, bitN, kind, total, &pcmstart ) ;
    if ( (wrtsize = fwrite( head, 1, 44, pFile)) != 44 )
    {
        error = CANT_SAVE ;
        goto FILEFIN_3 ;
    }

      //  後処理
  FILEFIN_3 :;
    fclose( pFile ) ;
    if( total == 0 ) remove( sndBufFile1 ) ;
  FILEFIN_2 :;
//    TL_free( pctrl ) ;
  FILEFIN_1 :;
//    TL_free( pring ) ;

	setMsgColor( recMesId[0], MOJI_COLOR ) ;	// 実行の表示色を変える

    return error ;
}

//  メモリ上へのサンプリング
static int recmemory()
{
    FILE  *pFile ;                //  ファイルポインタ
    char  *pring ;                //  リングバッファポインタ
    struct  buf_ctrl
    {
        int   sum ;
        int   apply_loc ;
        int   system_loc ;
        struct
        {
            char  *ptr ;
            char  reserve[8] ;
        }   buftbl[2] ;
    }   *pctrl ;                 //  リングバッファ管理テーブルポインタ
    char  *pdata ;                //  サンプリングデータ格納領域ポインタ
    int   pcmstart ;              //  PCMデータ相対開始位置
    int   error ;

	error = NOERR ;

    //  リングバッファとリングバッファ管理テーブルの領域の確保を行う
    //  リングバッファ数は２個
/*
    if ( (pring = TL_malloc( (2+1)*4096 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }
    if ( (pctrl = (struct buf_ctrl *)TL_malloc( (2+1)*12 )) == NULL )
    {
		error = OUT_OF_MEMORY ;
        goto MEMFIN_1 ;
    }
*/

// シェル対応のプログラムの場合ワークは,auto変数 or static変数を
// 使わないとWAV関数とうまくいかないこともある.何故かはわからない
	char buffer[ (2+1)*4096 + (2+1)*12 + 1024 ] ;
	pring = buffer ;
	pctrl = (struct buf_ctrl *)( buffer + (2+1)*4096 +512 );

    //  リングバッファ管理テーブルの作成
    pctrl->sum = 2 ;                           //  バッファ総数の設定
    pctrl->apply_loc = 0 ;                     //  アプリケーション位置のクリア
    WAV_makeTable( pring, (char *)pctrl ) ;

    //  サンプリングデータを格納する領域の確保
    if ( (pdata = TL_malloc( pcmSize )) == NULL )
    {
		error = OUT_OF_MEMORY ;
        goto MEMFIN_2 ;
    }

    //  録音前準備
    WAV_recPrepare( freq, bitN, kind, pdata, (void (*)())NULL ) ;

    //  録音開始
	MG_mosDisp( 0 ) ;

	setMsgColor( recMesId[0], EXE_COLOR ) ;		// 実行の表示色を変える

    SND_fm_timer_b_set( 0, 0 ) ;          //  音質向上の為タイマＢを停止
    WAV_rec( WAV_REC_COMPLETE, 0, pcmSize ) ;
    SND_fm_timer_b_start() ;              //  タイマＢを再起動

	setMsgColor( recMesId[0], MOJI_COLOR ) ;	// 実行の表示色を変える

	MG_mosDisp( 1 ) ;

    //  サンプリングデータをファイルに保存する
    if ( (pFile = fopen( sndBufFile1, "wb" )) == NULL )  //  ファイル作成
    {
        error = CANT_SAVE ;
        goto MEMFIN_3 ;
    }
    //  WAVEファイルの情報作成しファイルに書きだす
    //  （リングバッファ領域を作業領域として使用する）
    WAV_setWaveInfo_2( pring, freq, bitN, kind, pcmSize, &pcmstart ) ;
    if( fwrite( pring, 1, 44, pFile) != 44 )
    {
        error = CANT_SAVE ;
        goto MEMFIN_4 ;
    }
    //  サンプリングしたデータをファイルに書きだす
    if( fwrite( pdata, 1, pcmSize, pFile) != pcmSize )
    {
        error = CANT_SAVE ;
        goto MEMFIN_4 ;
    }

    //  後処理
MEMFIN_4:;
    fclose( pFile ) ;
	if( error )remove( sndBufFile1 ) ;
MEMFIN_3:;
    TL_free( pdata ) ;
MEMFIN_2:;
//    TL_free( pctrl ) ;
MEMFIN_1:;
//    TL_free( pring ) ;

    return error ;
}


// SNDデータ読み込み

int loadSndDataFile( char *name )
{
	int i ;
	int x1, x2 ;
	int fq, bit, kd, sz ;
	int sndLength ;
	int ret ;

	if( (ret = readSndData_init( name, &fq, &bit, &kd, &sz, 1 )) != NOERR )
	{
		return ret ;
	}

	sndLength = sz / (kd * bit/8) ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readSndData_end() ;
		return ret ;
	}

	for( i=0 ; i<sndLength ; i++ )
	{
		if( (ret = readSndData( i, &x1, &x2 )) != NOERR )
		{
			writeWavData_end() ;
			return ret ;
		}

		if( (ret = writeWavData( x1, x2 )) != NOERR )
		{
			readSndData_end() ;
			return ret ;
		}
	}
	writeWavData_end() ;
	readSndData_end() ;

    return NOERR ;
}

/* 重ね合わせ読み込み */

// WAV DATA

static int wavMixLoad( char *name, int vl1, int vl2 )
{
	int i ;
	int x1, x2, y1, y2 ;
	int fq, bit, kd, sz ;
	int fq2, bit2, kd2, sz2 ;
	int sndLength ;
	int ret ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}

	if( (ret = readWavData2_init( name, &fq2, &bit2, &kd2, &sz2, kd ))
															 != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	if( (sz / (kd * bit/8)) > (sz2 / (kd2 * bit2/8)) )
		sndLength = sz / (kd * bit/8) ;
	else
		sndLength = sz2 / (kd2 * bit2/8) ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readWavData2_end() ;
		readWavData_end() ;
		return ret ;
	}

	for( i=0 ; i<sndLength ; i++ )
	{
		if( (ret = readWavData( i, &x1, &x2 )) != NOERR )
		{
			writeWavData_end() ;
			readWavData2_end() ;
			return ret ;
		}

		if( (ret = readWavData2( i, &y1, &y2 )) != NOERR )
		{
			writeWavData_end() ;
			readWavData_end() ;
			return ret ;
		}

		x1 = ( x1 * vl1 + y1 * vl2 ) >> 8 ;
		x2 = ( x2 * vl1 + y2 * vl2 ) >> 8 ;

		if( (ret = writeWavData( x1, x2 )) != NOERR )
		{
			readWavData2_end() ;
			readWavData_end() ;
			return ret ;
		}
	}
	writeWavData_end() ;
	readWavData2_end() ;
	readWavData_end() ;

    return NOERR ;
}

// SND DATA

static int sndMixLoad( char *name, int vl1, int vl2 )
{
	int i ;
	int x1, x2, y1, y2 ;
	int fq, bit, kd, sz ;
	int fq2, bit2, kd2, sz2 ;
	int sndLength ;
	int ret ;

	if( (ret = readWavData_init( &fq, &bit, &kd, &sz )) != NOERR )
	{
		return ret ;
	}

	if( (ret = readSndData_init( name, &fq2, &bit2, &kd2, &sz2, kd ))
															 != NOERR )
	{
		readWavData_end() ;
		return ret ;
	}

	if( (sz / (kd * bit/8)) > (sz2 / (kd2 * bit2/8)) )
		sndLength = sz / (kd * bit/8) ;
	else
		sndLength = sz2 / (kd2 * bit2/8) ;

	if( (ret = writeWavData_init( fq, bit, kd, sz )) != NOERR )
	{
		readSndData_end() ;
		readWavData_end() ;
		return ret ;
	}

	for( i=0 ; i<sndLength ; i++ )
	{
		if( (ret = readWavData( i, &x1, &x2 )) != NOERR )
		{
			writeWavData_end() ;
			readSndData_end() ;
			return ret ;
		}

		if( (ret = readSndData( i, &y1, &y2 )) != NOERR )
		{
			writeWavData_end() ;
			readWavData_end() ;
			return ret ;
		}

		x1 = ( x1 * vl1 + y1 * vl2 ) >> 8 ;
		x2 = ( x2 * vl1 + y2 * vl2 ) >> 8 ;

		if( (ret = writeWavData( x1, x2 )) != NOERR )
		{
			readSndData_end() ;
			readWavData_end() ;
			return ret ;
		}
	}
	writeWavData_end() ;
	readSndData_end() ;
	readWavData_end() ;

    return NOERR ;
}


//  name データを読み込み

#define   readWavDataBind2  (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 ;                //  すでに読み込んだファイルデータ
static int   readMode ;                    //  1:mono out 2:stereo out

int  readWavData2_init( char *name, int *fq, int *bit, int *kd, int *sz,
																 int mode )
{
    int   ret ;                         //  戻り値
    int   pcmstart ;                    //  PCMデータ相対開始位置
    int   rdsz ;                        //  読み込むデータサイズ
    int   rdsize ;                      //  読み込まれたデータサイズ
    int   error ;
    int   i, x ;

	error = NOERR ;

	readMode = mode ;

    //  リングバッファの領域の確保を行う
    if ( (readRing = TL_malloc( 2 * readWavDataBind2 + 256 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }

    //  ファイルをオープンする
    if( (readFile = fopen( name, "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 * readWavDataBind2) ; i += 4 )
	{
		DWORD( readRing + i ) = x ;
	}
 	fread( readRing, 1, readWavDataBind2, 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 = ( readWavDataBind2 / ( (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  readWavData2( int point, int *left, int *right )
{
	int bindstart ;
	int rdsize ;
	int rp ;
	int i ;
	int x ;

	if( readBitno == 16 && readKind == 2 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind2 ;

		if( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind2 ;

	        rdsize =fread(readRing + bindstart, 1, readWavDataBind2, readFile);

	        if( rdsize < readWavDataBind2 )
    	    {
        		for( i=(rdsize >> 1) ; i<(readWavDataBind2 >> 1) ; i++ )
        			WORD( readRing + bindstart + i*2 ) = 0 ;
	        }

			readFileData += ( readWavDataBind2 >> 2 ) ;
		}

		rp = point - ( readBCount*readWavDataBind2 >> 2 ) ;
		if( rp >= ( readWavDataBind2 >> 2 ) )
			rp = ( readWavDataBind2 >> 2 ) - 1 ;
		if( rp < ( - readWavDataBind2 >> 2 ) )
			rp = ( - readWavDataBind2 >> 2 ) ;
		rp = rp + ( bindstart >> 2 ) ;
//		if( rp < 0 )
//			rp = ( readWavDataBind2 >> 2 )*2 + rp ;
		if( rp < 0 )
			rp = ( readWavDataBind2 >> 1 ) + rp ;

		if( rp < 0 )
			rp = 0 ;
//		if( rp >= ( readWavDataBind2 >> 2 )*2 )
//			rp = ( readWavDataBind2 >> 2 )*2 - 1 ;
		if( rp >= ( readWavDataBind2 >> 1 ) )
			rp = ( readWavDataBind2 >> 1 ) - 1 ;

		*left = WORD( readRing + (rp << 2) ) ;
		if( (*left) & 0x8000 )
			*left |= 0xffff0000 ;
		*right = WORD( readRing + (rp << 2) + 2 ) ;
		if( (*right) & 0x8000 )
			*right |= 0xffff0000 ;

		if( readMode == 1 )						// モノラル
			*left = ( *left + *right ) >> 1 ;

		return NOERR ;
	}
	else if( readBitno == 16 && readKind == 1 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind2 ;

		if( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind2 ;

	        rdsize = fread(readRing + bindstart, 1, readWavDataBind2, readFile);

	        if( rdsize < readWavDataBind2 )
    	    {
        		for( i=(rdsize >> 1) ; i<(readWavDataBind2 >> 1) ; i++ )
        			WORD( readRing + bindstart + i*2 ) = 0 ;
	        }

			readFileData += ( readWavDataBind2 >> 1 ) ;
		}

		rp = point - ( readBCount*readWavDataBind2 >> 1 ) ;
		if( rp >= ( readWavDataBind2 >> 1 ) )
			rp = ( readWavDataBind2 >> 1 ) - 1 ;
		if( rp < ( - readWavDataBind2 >> 1 ) )
			rp = ( - readWavDataBind2 >> 1 ) ;
		rp = rp + ( bindstart >> 1 ) ;
//		if( rp < 0 )
//			rp = ( readWavDataBind2 >> 1 )*2 + rp ;
		if( rp < 0 )
			rp = readWavDataBind2 + rp ;

		if( rp < 0 )
			rp = 0 ;
//		if( rp >= ( readWavDataBind2 >> 1 )*2 )
//			rp = ( readWavDataBind2 >> 1 )*2 - 1 ;
		if( rp >= readWavDataBind2 )
			rp = readWavDataBind2 - 1 ;

		*left = WORD( readRing + (rp << 1) ) ;
		if( (*left) & 0x8000 )
			*left |= 0xffff0000 ;
		*right = 0 ;

		if( readMode == 2 )						// ステレオ
			*right = *left ;

		return NOERR ;
	}
	else if( readBitno == 8 && readKind == 2 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind2 ;

		if( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind2 ;

	        rdsize =fread(readRing + bindstart, 1, readWavDataBind2, readFile);

	        if( rdsize < readWavDataBind2 )
    	    {
	       		for( i=rdsize ; i<readWavDataBind2 ; i++ )
    	   			BYTE( readRing + bindstart + i ) = 0x80 ;
	        }

			readFileData += ( readWavDataBind2 >> 1 ) ;
		}

		rp = point - ( readBCount*readWavDataBind2 >> 1 ) ;
		if( rp >= ( readWavDataBind2 >> 1 ) )
			rp = ( readWavDataBind2 >> 1 ) - 1 ;
		if( rp < ( - readWavDataBind2 >> 1 ) )
			rp = ( - readWavDataBind2 >> 1 ) ;
		rp = rp + ( bindstart >> 1 ) ;
//		if( rp < 0 )
//			rp = ( readWavDataBind2 >> 1 )*2 + rp ;
		if( rp < 0 )
			rp = readWavDataBind2 + rp ;

		if( rp < 0 )
			rp = 0 ;
//		if( rp >= ( readWavDataBind2 >> 1 )*2 )
//			rp = ( readWavDataBind2 >> 1 )*2 - 1 ;
		if( rp >= readWavDataBind2 )
			rp = readWavDataBind2 - 1 ;

		x = BYTE( readRing + (rp << 1) ) ;
		*left = ( x - 128 ) << 8 ;
		x = BYTE( readRing + (rp << 1) + 1 ) ;
		*right = ( x - 128 ) << 8 ;

		if( readMode == 1 )						// モノラル
			*left = ( *left + *right ) >> 1 ;

		return NOERR ;
	}
	else if( readBitno == 8 && readKind == 1 )
	{
	    bindstart = (readBCount % 2)*readWavDataBind2 ;

		if( point >= readFileData )
		{
        	readBCount++ ;
		    bindstart = (readBCount % 2)*readWavDataBind2 ;

	        rdsize =fread(readRing + bindstart, 1, readWavDataBind2, readFile);

	        if( rdsize < readWavDataBind2 )
    	    {
	       		for( i=rdsize ; i<readWavDataBind2 ; i++ )
    	   			BYTE( readRing + bindstart + i ) = 0x80 ;
	        }

			readFileData += readWavDataBind2 ;
		}

		rp = point - readBCount*readWavDataBind2 ;
		if( rp >= readWavDataBind2 )
			rp = readWavDataBind2 - 1 ;
		if( rp < ( - readWavDataBind2 ) )
			rp = ( - readWavDataBind2 ) ;
		rp = rp + bindstart ;
		if( rp < 0 )
			rp = readWavDataBind2 * 2 + rp ;

		if( rp < 0 )
			rp = 0 ;
		if( rp >= readWavDataBind2*2 )
			rp = readWavDataBind2*2 - 1 ;

		x = BYTE( readRing + rp ) ;
		*left = ( x - 128 ) << 8 ;
		*right = 0 ;

		if( readMode == 2 )						// ステレオ
			*right = *left ;

		return NOERR ;
	}

	return NOERR ;
}

int  readWavData2_end()
{
    fclose( readFile ) ;
    TL_free( readRing ) ;

    return NOERR ;
}


// SNDデータ読み込み

int  readSndData_init( char *name, int *fq, int *bit, int *kd, int *sz,
																 int mode )
{
    int   error ;
    int   i ;

	error = NOERR ;

	readMode = mode ;

    //  リングバッファの領域の確保を行う
    if ( (readRing = TL_malloc( 2 * readWavDataBind2 + 256 )) == NULL )
    {
        return OUT_OF_MEMORY ;
    }

    //  ファイルをオープンする
    if( (readFile = fopen( name, "rb" )) == NULL )  //  ファイルオープン
    {
        error = CANT_LOAD ;
        goto FILEFIN_2 ;
    }

    //  リングバッファを使用してファイルの情報を取得する
    if( fread( readRing, 32, 1, readFile ) < 1 )
    {
		error = CANT_LOAD ;
        goto FILEFIN_3 ;
    }
    readFreq = WORD( readRing + 24 ) * 1000 / 0x62 ;
	readFreq = ( readFreq + 50 )/100 * 100 ;
	readBitno = 8 ;
	readKind = 1 ;
	readPcmsz = DWORD( readRing + 12 ) ;

	for( i=0 ; i<(2 * readWavDataBind2) ; i += 4 )
	{
		DWORD( readRing + i ) = 0 ;
	}
 	fread( readRing, 1, readWavDataBind2, readFile ) ;

	readBCount = 0 ;                 //  バインドカウンター

	// すでに読み込んだファイルデータ
	readFileData = ( readWavDataBind2 / ( (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  readSndData( int point, int *left, int *right )
{
	int bindstart ;
	int rdsize ;
	int rp ;
	int i ;
	int x ;

    bindstart = (readBCount % 2)*readWavDataBind2 ;

	if( point >= readFileData )
	{
       	readBCount++ ;
	    bindstart = (readBCount % 2)*readWavDataBind2 ;

        rdsize = fread(readRing + bindstart, 1, readWavDataBind2, readFile);

        if( rdsize < readWavDataBind2 )
   	    {
       		for( i=rdsize ; i<readWavDataBind2 ; i++ )
       			BYTE( readRing + bindstart + i ) = 0 ;
        }
		readFileData += readWavDataBind2 ;
	}

	rp = point - readBCount*readWavDataBind2 ;
	if( rp >= readWavDataBind2 )
		rp = readWavDataBind2 - 1 ;
	if( rp < ( - readWavDataBind2 ) )
		rp = ( - readWavDataBind2 ) ;
	rp = rp + bindstart ;
	if( rp < 0 )
		rp = readWavDataBind2 * 2 + rp ;

	if( rp < 0 )
		rp = 0 ;
	if( rp >= readWavDataBind2*2 )
		rp = readWavDataBind2*2 - 1 ;

	x = BYTE( readRing + rp ) ;
	if( x < 128 )x = 128 - x ;
	*left = ( x - 128 ) << 8 ;
	*right = 0 ;

	if( readMode == 2 )						// ステレオ
		*right = *left ;

	return NOERR ;
}

int  readSndData_end()
{
    fclose( readFile ) ;
    TL_free( readRing ) ;

    return NOERR ;
}

