/****************************************************
 *													*
 *	Dreamcast Sound Library							*
 *			Library Development Kit					*
 *													*
 *		Copyright 1997,1998 (C)SEGA Enterprises		*
 *			Programmed By T.Jokagi					*
 *													*
 ****************************************************/

#ifndef	_SG_SD_H_
#define	_SG_SD_H_

#include	<sg_xpt.h>

/*****************************************************
 *
 *	定数定義
 *
 */
/*
 *	各種音源の最大ポート数
 */
#define	SDD_MIDI_PORT_MAX		(8)
#define	SDD_SHOT_PORT_MAX		(8)
#define	SDD_PSTM_PORT_MAX		(4)

/*	PCMストリーム１ポートのチャンネル数  */
#define	SDD_PSTM_PORT_CH_MAX	(2)

/*
 *	MIDIメッセージ
 */
#define	SDD_MIDI_NOTE_OFF		(0x80)
#define	SDD_MIDI_NOTE_ON		(0x90)
#define	SDD_MIDI_MONO_PRES		(0xA0)
#define	SDD_MIDI_CTL_CHG		(0xB0)
#define	SDD_MIDI_PRG_CHG		(0xC0)
#define	SDD_MIDI_POLY_PRES		(0xD0)
#define	SDD_MIDI_PITCH_BEND		(0xE0)

/*
 *	PCMストリームチャンネル別名
 */
#define	SDD_PSTM_LEFT_CH		(0x00)
#define	SDD_PSTM_RIGHT_CH 		(0x01)
#define	SDD_PSTM_ALL_CH 		(0xFF)

#define	SDD_PSTM_FREQ_44100		(0x0000)
#define	SDD_PSTM_FREQ_22050		(0x7800)
#define	SDD_PSTM_FREQ_11025		(0x7000)

/*	メモリブロック転送で関数を登録しない場合  */
#define	SDD_MEMBLK_NO_FUNC		(( SD_MEMBLK_CALLBACK_FUNC)0x00000000)
/*	メモリブロック転送で同期モードを行う場合  */
#define	SDD_MEMBLK_SYNC_FUNC	(( SD_MEMBLK_CALLBACK_FUNC)0xFFFFFFFF)

/*****************************************************
 *
 *	マクロ関数宣言
 *
 */
#define	SDD_INT32(data)							\
	( (((data >> 24) & 0x000000FF)      )		\
	| (((data >> 16) & 0x000000FF) <<  8)		\
	| (((data >>  8) & 0x000000FF) << 16)		\
	| (((data      ) & 0x000000FF) << 24))

#define	SDD_CHAR32(d1,d2,d3,d4)					\
	( ( d1      )								\
	| ( d2 <<  8)								\
	| ( d3 << 16)								\
	| ( d4 << 24))

/*****************************************************
 *
 *	データタイプ定義
 *
 */

/********************************
 *
 *	列挙体タイプ定義
 *
 */
/*
 *	サウンドエラー型定義
 */
enum SDE_ERR
{
	SDE_ERR_NOTHING					= 0x00000000,	/*	ノーエラー  */
	SDE_ERR_PRM_OVER_RANGE			= 0x03000001,	/*	パラメータレンジオーバー  */
	SDE_ERR_HANDLE_NO_ENOUGH		= 0x07000001,	/*	ハンドルの空きが無い  */
	SDE_ERR_HANDLE_ILLEGAL_VALUE	= 0x07000101,	/*	不正なハンドル  */
	SDE_ERR_HANDLE_NULL				= 0x07000102,	/*	ハンドルが0アドレスを指している  */
	SDE_ERR_PTR_ILLEGAL_VALUE		= 0x07000202,	/*	ポインタのアドレスがおかしい  */
	SDE_ERR_PTR_NULL				= 0x07000202,	/*	ポインタが0アドレスを指している  */
	SDE_ERR_DATA_ILLEGAL_TYPE		= 0x09000001,	/*	データタイプが違う  */
	SDE_ERR_DATA_ILLEGAL_VER		= 0x09000002,	/*	データバージョンが古い  */
	SDE_ERR_DATA_NOTHING			= 0x09000003,	/*	データが無い，もしくは未設定  */
	SDE_ERR_HOST_CMD_BUF_NO_ENOUGH	= 0x0A000001,	/*	ホストコマンドバッファフル  */
	SDE_ERR_SND_DRV_PROBLEM			= 0x0B000001,	/*	サウンドドライバの動作不良  */
	SDD_ERR_SND_DRV_ILLEGAL_VER		= 0x0B000002,	/*	ドライバとのバージョン不一致  */
	SDE_ERR_SND_DRV_BUSY			= 0x0B000003,	/*	ドライバ処理中  */
	SDE_ERR_NO_INIT					= 0x0D000001,	/*	未初期化  */
	SDD_ERR_ALREADY_INIT			= 0x0D000002,	/*	すでに初期化済み  */
	SDE_ERR_HARD_WARE				= 0x0F000001,	/*	ハードウェア動作不良  */
	SDE_ERR_UNKNOW_NUM				= 0x7FFFFFFF	/*	未知のエラー  */
};
typedef enum SDE_ERR	SDE_ERR;

/*
 *	サウンドデータ型定義
 */
enum SDE_DATA_TYPE
{
	SDE_DATA_TYPE_SND_DRV			= SDD_CHAR32('S','D','R','V'),	/*	SDRV  */
	SDE_DATA_TYPE_MULTI_UNIT		= SDD_CHAR32('S','M','L','T'),	/*	SMLT  */
	SDE_DATA_TYPE_MIDI_SEQ_DATA		= SDD_CHAR32('S','M','S','D'),	/*	SMSD  */
	SDE_DATA_TYPE_MIDI_SEQ_BANK		= SDD_CHAR32('S','M','S','B'),	/*	SMSB  */
	SDE_DATA_TYPE_MIDI_PRG_BANK		= SDD_CHAR32('S','M','P','B'),	/*	SMPB  */
	SDE_DATA_TYPE_SHOT_DATA			= SDD_CHAR32('S','O','S','D'),	/*	SOSD  */
	SDE_DATA_TYPE_SHOT_BANK			= SDD_CHAR32('S','O','S','B'),	/*	SOSB  */
	SDE_DATA_TYPE_PSTM_DATA			= SDD_CHAR32('S','P','S','D'),	/*	SPSD  */
	SDE_DATA_TYPE_PSTM_RING_BUF		= SDD_CHAR32('S','P','S','R'),	/*	SPSR  */
	SDE_DATA_TYPE_FX_OUT_BANK		= SDD_CHAR32('S','F','O','B'),	/*	SFOB  */
	SDE_DATA_TYPE_FX_PRG_BANK		= SDD_CHAR32('S','F','P','B'),	/*	SFPB  */
	SDE_DATA_TYPE_FX_PRG_WRK		= SDD_CHAR32('S','F','P','W')	/*	SFPW  */
};
typedef enum SDE_DATA_TYPE	SDE_DATA_TYPE;

/*
 *	サウンド空間型定義
 */
enum SDE_SPACE
{
	SDE_SPACE_MONO		= SDD_CHAR32('M','O','N','O'),	/*	MONO  */
	SDE_SPACE_STEREO	= SDD_CHAR32('S','T','R','O')	/*	STRO  */
};
typedef enum SDE_SPACE	SDE_SPACE;

/*
 *	サウンドPCMの種類型定義
 */
enum SDE_PCM_TYPE
{
	SDE_PCM_TYPE_8BIT_PCM,
	SDE_PCM_TYPE_16BIT_PCM,
	SDE_PCM_TYPE_4BIT_ADPCM
};
typedef enum SDE_PCM_TYPE	SDE_PCM_TYPE;

/*
 *	サウンドメモリブロック転送ステータス型定義
 */
enum SDE_MEMBLK_STAT
{
	SDE_MEMBLK_STAT_TRANSFER_REMAIN,
	SDE_MEMBLK_STAT_TRANSFER_FINISHED,
	SDE_MEMBLK_STAT_TRANSFER_PROGRESS
};
typedef enum SDE_MEMBLK_STAT	SDE_MEMBLK_STAT;

/********************************
 *
 *	単純タイプ定義
 *
 */
typedef Void	( *SD_MEMBLK_CALLBACK_FUNC)( Void *first_arg);

/********************************
 *
 *	構造体タイプ定義
 *
 */
/*
 *	サウンドバージョン型定義
 */
struct SDS_VER
{
	Uint8	m_MajorVer;			/*	メジャーバージョン  */
	Uint8	m_MinorVer;			/*	マイナーバージョン  */
	Uint8	m_DebugVer;			/*	デバグバージョン  */
	Uint8	rsv;				/*	予約領域  */
};
typedef struct SDS_VER	SDS_VER;

/*
 *	サウンドMIDIメッセージ型定義
 */
struct SDS_MIDI_MES
{
	Uint8	m_Member[ 0x04];
};
typedef struct SDS_MIDI_MES	SDS_MIDI_MES;

/*
 *	FXアウトプットパラメータ
 */
struct SDS_FX_OUT_PRM
{
	Sint8	m_Lev;
	Sint8	m_Ch;
};
typedef struct SDS_FX_OUT_PRM	SDS_FX_OUT_PRM;

/*
 *	モジュール共通のステータス型定義
 */
struct SDS_MODULE_COMMON_STAT
{
	Sint8	m_HostCmdRsvNum;		/*	ホストコマンドリザーブサイズ  */
	Sint8	m_HostCmdDelayTime;		/*	ホストコマンド送信遅延時間  */
	Sint16	rsv;					/*	予約領域  */
};
typedef struct SDS_MODULE_COMMON_STAT	SDS_MODULE_COMMON_STAT;

/*
 *	サウンドMIDIポートのステータス型定義
 */
struct SDS_MIDI_STAT
{
	SDS_MODULE_COMMON_STAT	m_CommonStat;	/*	コモンステータス  */

	Sint8	m_Vol;				/*	ボリューム  */
	Sint8	m_Pan;				/*	パンポット  */
	Sint8	m_FxLev;			/*	FXレベル  */
	Sint8	m_DrctLev;			/*	ダイレクトレベル  */
	Sint16	m_Pitch;			/*	ピッチ  */
	Sint16	m_Speed;			/*	スピード  */
	Uint32	m_TotalBeatTime;	/*	総演奏拍数  */
	Sint32	m_CurAdr;			/*	カレント演奏アドレス  */
};
typedef struct SDS_MIDI_STAT	SDS_MIDI_STAT;

/*
 *	サウンドワンショットポートのステータス型定義
 */
struct SDS_SHOT_STAT
{
	SDS_MODULE_COMMON_STAT	m_CommonStat;	/*	コモンステータス  */

	Sint8	m_Vol;				/*	ボリューム  */
	Sint8	m_Pan;				/*	パンポット  */
	Sint8	m_FxLev;			/*	FXレベル  */
	Sint8	m_DrctLev;			/*	ダイレクトレベル  */
	Sint16	m_Pitch;			/*	ピッチ  */
	Sint16	m_Speed;			/*	スピード  */
	Uint32	m_TotalSmpFrame;	/*	総演奏サンプル数  */
	Sint32	m_CurAdr;			/*	カレント演奏アドレス  */
};
typedef struct SDS_SHOT_STAT	SDS_SHOT_STAT;

/*
 *	サウンドPCMストリームポートのステータス型定義
 */
struct SDS_PSTM_STAT
{
	SDS_MODULE_COMMON_STAT	m_CommonStat;	/*	コモンステータス  */

	Sint8	m_Vol;				/*	ボリューム  */
	Sint8	m_Pan;				/*	パンポット  */
	Sint8	m_FxLev;			/*	FXレベル  */
	Sint8	m_DrctLev;			/*	ダイレクトレベル  */
	Sint16	m_Pitch;			/*	ピッチ  */
	Sint16	m_Speed;			/*	スピード  */
	Uint32	m_TotalSmpFrame;	/*	総演奏サンプル数  */
	Sint32	m_CurAdr;			/*	カレント演奏アドレス  */
};
typedef struct SDS_PSTM_STAT	SDS_PSTM_STAT;

/*
 *	GDDAのステータス型定義
 */
struct SDS_GDDA_STAT
{
	SDS_MODULE_COMMON_STAT	m_CommonStat;	/*	コモンステータス  */

	Sint8	m_LeftVol;			/*	左チャンネルボリューム  */
	Sint8	m_RightVol;			/*	右チャンネルボリューム  */
	Sint8	m_LeftPan;			/*	左チャンネルパンポット  */
	Sint8	m_RightPan;			/*	右チャンネルパンポット  */
};
typedef struct SDS_GDDA_STAT	SDS_GDDA_STAT;

/*
 *	メモリブロック型定義
 */
struct SDS_MEM_BLK
{
	Uint32	m_Member[ 8];
};
typedef struct SDS_MEM_BLK	*SDMEMBLK;		/*	メモリブロックハンドル  */

/*
 *	ポートハンドル型定義
 */
struct SDS_PORT_REF
{
	Void	*m_Ref;	/*	内容は隠蔽しているので直接操作は保証しません  */
};
typedef struct SDS_PORT_REF	SDS_PORT_REF;
typedef struct SDS_PORT_REF	*SDHANDLE;

typedef SDHANDLE	*SDMIDI;	/*	MIDIポートハンドル  */
typedef SDHANDLE	*SDSHOT;	/*	ワンショットポートハンドル  */
typedef SDHANDLE	*SDPSTM;	/*	PCMストリームポートハンドル  */

/*****************************************************
 *
 *	プロトタイプ宣言
 *
 */
/*
 *	サウンドシステムAPI
 */
EXTERN SDE_ERR	sdDrvInit( SDMEMBLK handle);
EXTERN SDE_ERR	sdDrvGetBuildinInfo( Void **snd_drv_ptr, Sint32 *snd_drv_sz, SDS_VER *snd_drv_ver);
EXTERN SDE_ERR	sdDrvGetVer( SDS_VER *drv_ver);
EXTERN SDE_ERR	sdDrvGetExecuteCounter( Uint32 *count_num);
EXTERN SDE_ERR	sdLibInit( Void *wrk_ptr, Sint32 mem_blk_handle_max, Sint32 second_host_cmd_max);
EXTERN SDE_ERR	sdLibGetBuildDate( Void *time_string);
EXTERN SDE_ERR	sdLibGetVer( SDS_VER *lib_ver);
EXTERN Void		sdSysServer( Void);

/*
 *	グローバルサウンドコントロールAPI
 */
EXTERN SDE_ERR	sdSndSetMasterVol( Sint8 vol);
EXTERN SDE_ERR	sdSndSetSpace( SDE_SPACE space);
EXTERN SDE_ERR	sdSndSetFxPrg( Sint8 new_fx_prg_num, Sint8 new_fx_out_num);
EXTERN SDE_ERR	sdSndSetFxOutPrm( Sint8 out_num, Sint8 out_pan, Sint8 out_lev);
EXTERN SDE_ERR	sdSndGetFxPrg( Sint8 *cur_fx_prg_num);
EXTERN SDE_ERR	sdSndClearFxPrg( Void);
EXTERN SDE_ERR	sdSndSetFxOut( Sint8 new_fx_out_num);
EXTERN SDE_ERR	sdSndGetFxOut( Sint8 *cur_fx_out_num);
EXTERN SDE_ERR	sdSndStopAll( Void);
EXTERN SDE_ERR	sdQsndSetPos( Sint8 *pos);

/*
 *	サウンドデータユーティリティAPI
 */
EXTERN SDE_ERR	sdDownloadMultiUnit( SDMEMBLK handle);
EXTERN SDE_ERR	sdDownloadSingleBank( SDMEMBLK handle, SDE_DATA_TYPE data_type, Sint8 bank_num);
EXTERN SDE_ERR	sdMultiUnitDownload( SDMEMBLK handle);
EXTERN SDE_ERR	sdBankDownload( SDMEMBLK handle, SDE_DATA_TYPE data_type, Sint8 bank_num);

/*
 *	サウンドメモリコントロールAPI
 */
EXTERN SDE_ERR	sdSndMemGetBankStat(  SDE_DATA_TYPE data_type, Sint8 bank_num, Sint32 *allocate_ptr, Sint32 *allocate_size);

/*
 *	メモリブロック転送API
 */
EXTERN SDE_ERR	sdMemBlkCleate( SDMEMBLK *handle);
EXTERN SDE_ERR	sdMemBlkDestroy( SDMEMBLK handle);
EXTERN SDE_ERR	sdMemBlkSetPrm( SDMEMBLK handle, Void *src_blk_ptr, Sint32 src_blk_sz, SD_MEMBLK_CALLBACK_FUNC callback_func, Void *callback_first_arg);
EXTERN SDE_ERR	sdMemBlkGetStat( SDMEMBLK handle, SDE_MEMBLK_STAT *stat);

/*
 *	サウンドモジュールコントロールAPI
 */
/*	MIDIポート  */
EXTERN SDE_ERR	sdMidiClosePort( SDMIDI handle);
EXTERN SDE_ERR	sdMidiContinue( SDMIDI handle);
EXTERN SDE_ERR	sdMidiGetCurAdr( SDMIDI handle, Sint32 *cur_adr);
EXTERN SDE_ERR	sdMidiGetStat( SDMIDI handle, SDS_MIDI_STAT *midi_stat);
EXTERN SDE_ERR	sdMidiGetTotalBeatTime( SDMIDI handle, Uint32 *cur_beat_time);
EXTERN SDE_ERR	sdMidiOpenPort( SDMIDI *handle);
EXTERN SDE_ERR	sdMidiPause( SDMIDI handle);
EXTERN SDE_ERR	sdMidiPlay( SDMIDI handle, Sint8 bank_num, Sint8 list_num, Sint8 priority);
EXTERN SDE_ERR	sdMidiResetPrm( SDMIDI handle);
EXTERN SDE_ERR	sdMidiResetAllPrm( Void);
EXTERN SDE_ERR	sdMidiSetDrctLev( SDMIDI handle, Sint8 lev);
EXTERN SDE_ERR	sdMidiSetFxLev( SDMIDI handle, Sint8 fx_lev);
EXTERN SDE_ERR	sdMidiSetMes( SDMIDI handle, SDS_MIDI_MES *midi_mes_ptr, Uint8 midi_mes,... );
EXTERN SDE_ERR	sdMidiSetPan( SDMIDI handle, Sint8 pan, Sint32 fade_time);
EXTERN SDE_ERR	sdMidiSetPitch( SDMIDI handle, Sint16 pitch, Sint32 fade_time);
EXTERN SDE_ERR	sdMidiSetHostCmdRsv( SDMIDI handle, Sint8 rsv_num);
EXTERN SDE_ERR	sdMidiSetSpeed( SDMIDI handle, Sint16 speed, Sint32 fade_time);
EXTERN SDE_ERR	sdMidiSetVol( SDMIDI handle, Sint8 vol, Sint32 fade_time);
EXTERN SDE_ERR	sdMidiStop( SDMIDI handle);
EXTERN SDE_ERR	sdMidiStopAll( Void);
EXTERN SDE_ERR	sdMidiSendMes( SDMIDI handle, SDS_MIDI_MES *midi_mes_ptr, Sint8 priority);

/*	ワンショットポート  */
EXTERN SDE_ERR	sdShotClosePort( SDSHOT handle);
EXTERN SDE_ERR	sdShotGetCurAdr( SDSHOT handle, Sint32 *cur_smp_adr);
EXTERN SDE_ERR	sdShotGetStat( SDSHOT handle, SDS_SHOT_STAT *sstm_stat);
EXTERN SDE_ERR	sdShotGetTotalSmpFrame( SDSHOT handle, Uint32 *cur_smp_frame);
EXTERN SDE_ERR	sdShotOpenPort( SDSHOT *handle);
EXTERN SDE_ERR	sdShotPlay( SDSHOT handle, Sint8 bank_num, Sint8 list_num, Sint8 priority);
EXTERN SDE_ERR	sdShotResetPrm( SDSHOT handle);
EXTERN SDE_ERR	sdShotResetAllPrm( Void);
EXTERN SDE_ERR	sdShotSetDrctLev( SDSHOT handle, Sint8 drct_lev);
EXTERN SDE_ERR	sdShotSetFxCh( SDSHOT handle, Sint8 fx_in_ch, Sint8 fx_base_lev);
EXTERN SDE_ERR	sdShotSetFxLev( SDSHOT handle, Sint8 fx_lev);
EXTERN SDE_ERR	sdShotSetHostCmdRsvNum( SDSHOT handle, Sint8 rsv_num);
EXTERN SDE_ERR	sdShotSetHostCmdDelayTime( SDSHOT handle, Sint8 delay_time);
EXTERN SDE_ERR	sdShotSetPan( SDSHOT handle, Sint8 pan, Sint32 fade_time);
EXTERN SDE_ERR	sdShotSetPitch( SDSHOT handle, Sint16 pitch, Sint32 fade_time);
EXTERN SDE_ERR	sdShotSetSpeed( SDSHOT handle, Sint16 speed, Sint32 fade_time);
EXTERN SDE_ERR	sdShotSetVol( SDSHOT handle, Sint8 vol, Sint32 fade_time);
EXTERN SDE_ERR	sdShotStop( SDSHOT handle);
EXTERN SDE_ERR	sdShotStopAll( Void);

/*	PCMストリームポート  */
EXTERN SDE_ERR	sdPstmClosePort( SDPSTM handle);
EXTERN SDE_ERR	sdPstmGetCurAdr( SDPSTM handle, Sint8 target_ch, Sint32 *cur_smp_adr);
EXTERN SDE_ERR	sdPstmGetStat( SDPSTM handle, Sint8 target_ch, SDS_PSTM_STAT *pstm_stat);
EXTERN SDE_ERR	sdPstmGetTotalSmpFrame( SDPSTM handle, Sint8 target_ch, Uint32 *cur_smp_frame);
EXTERN SDE_ERR	sdPstmIsTransferWaveData( SDPSTM handle, Sint8 ch, Sint32 data_sz, Bool *flg);
EXTERN SDE_ERR	sdPstmOpenPort( SDPSTM *handle, Sint8 use_ch, Sint8 ring_buf_num, ...);
EXTERN SDE_ERR	sdPstmPlay( SDPSTM handle, SDE_PCM_TYPE pcmType, Uint16 oct_fns, Sint8 priority);
EXTERN SDE_ERR	sdPstmResetPrm( SDPSTM handle);
EXTERN SDE_ERR	sdPstmResetAllPrm( Void);
EXTERN SDE_ERR	sdPstmTransferWaveData( SDPSTM handle, Sint8 ch, SDMEMBLK mem_blk_ptr);
EXTERN SDE_ERR	sdPstmSetBaseVol( SDPSTM handle, Sint8 base_vol);
EXTERN SDE_ERR	sdPstmSetDrctLev( SDPSTM handle, Sint8 lev);
EXTERN SDE_ERR	sdPstmSetFxCh( SDPSTM handle, Sint8 fx_in_ch, Sint8 fx_base_lev);
EXTERN SDE_ERR	sdPstmSetFxLev( SDPSTM handle, Sint8 fx_lev);
EXTERN SDE_ERR	sdPstmSetPan( SDPSTM handle, Sint8 target_ch, Sint8 pan, Sint32 fade_time);
EXTERN SDE_ERR	sdPstmSetPitch( SDPSTM handle, Sint16 pitch, Sint32 fade_time);
EXTERN SDE_ERR	sdPstmSetSpeed( SDPSTM handle, Sint16 speed, Sint32 fade_time);
EXTERN SDE_ERR	sdPstmSetVol( SDPSTM handle, Sint8 target_ch, Sint8 vol, Sint32 fade_time);
EXTERN SDE_ERR	sdPstmStop( SDPSTM handle);
EXTERN SDE_ERR	sdPstmStopAll( Void);

/*	GD-DA  */
EXTERN SDE_ERR	sdGddaGetStat( SDS_GDDA_STAT *stat);
EXTERN SDE_ERR	sdGddaResetPrm( Void);
EXTERN SDE_ERR	sdGddaSetPan( Sint8 leftPan, Sint8 right_pan);
EXTERN SDE_ERR	sdGddaSetVol( Sint8 leftVol, Sint8 right_vol);

/*****************************************************
 *
 *	外部変数宣言
 *
 */

#endif	/*	#ifndef	SDD_SG_SD_H  */

/*EOF*/
