/*
 *	clipadp.h
 *
 *	2-bit ADPCM Decoder
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2006 Naoyuki Sawa
 *
 *	* Wed Dec 20 00:13:10 JST 2006 Naoyuki Sawa
 *	- 作成開始。
 *	* Wed Dec 20 17:31:02 JST 2006 Naoyuki Sawa
 *	- 1st リリース。
 *	* Thu Dec 21 11:18:32 JST 2006 Naoyuki Sawa
 *	- ADPCMCHANNEL構造体を扱い易く並び替えて、ASM版adpcm_mix1()を最適化しました。
 *	* Thu Mar 01 01:53:43 JST 2007 Naoyuki Sawa
 *	- adpcm_stat()を追加しました。
 */
#ifndef __CLIP_ADP_H__
#define __CLIP_ADP_H__

/****************************************************************************
 *	定数、構造体
 ****************************************************************************/

/* PCEWAVEINFO.type の独自拡張 */
#define PW_TYPE_2BITADPCM	3
#define PW_TYPE_ADPCM_X		(PW_TYPE_2BITADPCM|PW_TYPE_VR|PW_TYPE_ADP_INI)
#define PW_TYPE_ADPCM_X_NI	(PW_TYPE_2BITADPCM|PW_TYPE_VR)

#define ADPCMBUFLEN		320	/* =16000/50 … 1[tick](=1/50[sec])当たりのサンプル数 */

/* アセンブラコードから直接参照するため、レイアウト固定です!! */
//typedef struct _ADPCMCHANNEL {
//	int loop;			/* + 0,4: 0=停止, 1～=残りループ回数, -1=無限ループ */
//	int pcm;			/* + 4,4: 出力PCM値 */
//	short data;			/* + 8,2: 入力ADPCM値のバッファ */
//	short delta;			/* +10,2: ⊿値 */
//	short progress;			/* +12,2: 進行カウンタ */
//	short rate;			/* +14,2: サンプリングレート */
//	int len;			/* +16,4: 残り出力サンプル数 */
//	const unsigned char* ptr;	/* +20,4: ADPCMデータ走査位置 */
//	int init_len;			/* +24,4: 残り出力サンプル数のリセット値 */
//	const unsigned char* init_ptr;	/* +28,4: ADPCMデータ走査位置のリセット値 */
//} ADPCMCHANNEL;				/* =32 */
//↓* Thu Dec 21 11:18:32 JST 2006 Naoyuki Sawa
//↓- ADPCMCHANNEL構造体を扱い易く並び替えて、ASM版adpcm_mix1()を最適化しました。
typedef struct _ADPCMCHANNEL {
	int pcm;			/* + 0,4: 出力PCM値 */
	short data;			/* + 4,2: 入力ADPCM値のバッファ */
	short delta;			/* + 6,2: ⊿値 */
	short progress;			/* + 8,2: 進行カウンタ */
	short rate;			/* +10,2: サンプリングレート */
	int len;			/* +12,4: 残り出力サンプル数 */
	const unsigned char* ptr;	/* +16,4: ADPCMデータ走査位置 */
	int loop;			/* +20,4: 0=停止, 1～=残りループ回数, -1=無限ループ */
	int init_len;			/* +24,4: 残り出力サンプル数のリセット値 */
	const unsigned char* init_ptr;	/* +28,4: ADPCMデータ走査位置のリセット値 */
} ADPCMCHANNEL;				/* =32 */

typedef struct _ADPCMDRIVER {
	int nch;			/* チャネル数 */
	ADPCMCHANNEL* pch/*[nch]*/;	/* チャネル構造体 */
} ADPCMDRIVER;

/* framadp.c */
void adpcm_mix1(ADPCMCHANNEL* pch, int mixbuf[/*ADPCMBUFLEN*/]);
void adpcm_mix2(short wbuff[/*ADPCMBUFLEN*/], int mixbuf[/*ADPCMBUFLEN*/]);

/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/

/* 2-bit ADPCM Decoderを起動します。
 * [in]
 *	nch		チャネル数。
 * [note]
 *	* adpcm_play()を使う前にadpcm_init()を呼び出して、2-bit ADPCM Decoderを起動しておいてください。
 *	* この関数は、内部でstream_play()を呼び出しています。
 *	  stream_play()を呼ぶと、サウンド割り込みベクタがフックされます。
 *	  プログラム終了前にadpcm_exit()を呼び出して、ベクタを復元してください。
 *	  ただし、ライブラリが終了時に自動的にフックを復元するので、adpcm_exit()を呼ばずに終了しても安全です。
 */
void adpcm_init(int nch);

/* 2-bit ADPCM Decoderを停止します。
 * [note]
 *	* 2-bit ADPCM Decoderが起動していなければ、この関数は何も行いません。
 */
void adpcm_exit();

/* 2-bit ADPCM形式のppdデータを再生します。
 * [in]
 *	ch		チャネル番号。(1～nch-1)
 *	data		2-bit ADPCM形式のppdデータ。(ファイルイメージの先頭アドレス)
 *	loop		1～ = ループ回数, -1 = 無限ループ。
 * [note]
 *	* この関数の使い方は、sound_play()と同じです。
 *	  clippce.hのsound_play()のコメントを参照してください。
 *	* この関数は、2-bit ADPCM形式のppdデータの再生にのみ利用できます。
 *	  2-bit ADPCM形式以外のppdを指定すると、エラー終了します。
 *	  2-bit ADPCM形式以外のppdを再生するには、sound_play()を利用してください。
 */
void adpcm_play(int ch, const void* data, int loop);

/* 2-bit ADPCM形式のppdデータ再生を停止します。
 * [in]
 *	ch		チャネル番号。(1～nch-1)
 * [note]
 *	* 指定されたチャネルが再生中でない場合は、この関数は何も行いません。
 */
void adpcm_stop(int ch);

/* 指定された2-bit ADPCMチャネルが、再生中か停止中かを調べます。
 * [in]
 *	ch		チャネル番号。(1～nch-1)
 * [out]
 *	戻り値		再生中ならば0以外の値を返します。
 *			停止中ならば0を返します。
 * [note]
 *	* 2007/03/01現在の実装は、ADPCMCHANNEL.loopの値をそのまま返しているので、
 *	  戻り値は、{0=停止, 1～=残りループ回数, -1=無限ループ} となっています。
 *	  ただし、今後もし実装を変更した場合に、戻り値が変わる可能性があります。
 *	  戻り値を、上のように仮定してコーディングしないよう、注意してください。
 */
int adpcm_stat(int ch);

#endif /*__CLIP_ADP_H__*/
