diff pmdwin.h @ 0:c55ea9478c80

Hello Gensokyo!
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 21 May 2013 10:29:21 +0200
parents
children e3849cd10ad3
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/pmdwin.h
@@ -0,0 +1,521 @@
+//=============================================================================
+//	Professional Music Driver [P.M.D.] version 4.8
+//			Programmed By M.Kajihara
+//			Windows Converted by C60
+//=============================================================================
+
+#ifndef PMDWIN_H
+#define PMDWIN_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "opna.h"
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+#ifndef __cplusplus
+typedef unsigned char bool;
+#endif
+extern const int *const efftbl[];
+
+#ifdef __cplusplus
+extern "C" {
+    void lfg_srand(unsigned int seed);
+    unsigned int lfg_rand(void);
+};
+#endif
+
+
+//=============================================================================
+//	バージョン情報
+//=============================================================================
+#define	DLLVersion			 36		// 上1桁:major, 下2桁:minor version
+#define	InterfaceVersion	117		// 上1桁:major, 下2桁:minor version
+
+
+//=============================================================================
+//	DLL の戻り値
+//=============================================================================
+#define	PMDWIN_OK				 	  0		// 正常終了
+#define	ERR_OPEN_MUSIC_FILE			  1		// 曲 データを開けなかった
+#define	ERR_WRONG_MUSIC_FILE		  2		// PMD の曲データではなかった
+#define	ERR_WRONG_PARTNO			 30		// パート番号が不適
+//#define	ERR_ALREADY_MASKED			 31		// 指定パートはすでにマスクされている
+#define	ERR_NOT_MASKED				 32		// 指定パートはマスクされていない
+#define	ERR_MUSIC_STOPPED			 33		// 曲が止まっているのにマスク操作をした
+#define	ERR_EFFECT_USED				 34		// 効果音で使用中なのでマスクを操作できない
+#define	ERR_OUT_OF_MEMORY			 99		// メモリを確保できなかった
+#define	ERR_OTHER					999		// その他のエラー
+
+
+//----------------------------------------------------------------------------
+//	PMDWin専用の定義
+//----------------------------------------------------------------------------
+#define	SOUND_55K			  55555
+#define	SOUND_55K_2			  55466
+#define	SOUND_48K			  48000
+#define	SOUND_44K			  44100
+#define	SOUND_22K			  22050
+#define	SOUND_11K			  11025
+#define	DEFAULT_REG_WAIT	  15000
+#define	MAX_PCMDIR				 64
+#define	MAX_MEMOBUF			   1024
+
+//----------------------------------------------------------------------------
+//	その他定義
+//----------------------------------------------------------------------------
+//#define	nbufsample			  30000
+#define nbufsample 8192
+#define	OPNAClock		(3993600*2)
+
+#define	NumOfFMPart			      6
+#define	NumOfSSGPart		      3
+#define	NumOFOPNARhythmPart	      1
+#define	NumOfAllPart		(NumOfFMPart+NumOfSSGPart+NumOFOPNARhythmPart)
+
+#pragma pack( push, enter_include1 )
+#pragma pack(2)
+
+typedef struct stereo16bittag
+{
+	short left;
+} Stereo16bit;
+
+#pragma pack( pop, enter_include1 )
+
+//#define ver 		"4.8o"
+//#define vers		0x48
+//#define verc		"o"
+//#define date		"Jun.19th 1997"
+
+//#define max_part1	22		// 0クリアすべきパート数(for PMDPPZ)
+#define max_part2	11		// 初期化すべきパート数  (for PMDPPZ)
+
+#define mdata_def	64
+#define voice_def	 8
+#define effect_def	64
+
+#define fmvd_init	0		// 98は88よりもFM音源を小さく
+
+
+/******************************************************************************
+;	WORK AREA
+******************************************************************************/
+typedef struct PMDworktag {
+	int		partb;				//	処理中パート番号
+	int		tieflag;			//	&のフラグ(1 : tie)
+	int		volpush_flag;		//	次の1音音量down用のflag(1 : voldown)
+	int		rhydmy;				//	R part ダミー演奏データ
+	int		fmsel;				//	FM 表(=0)か裏(=0x100)か flag
+	int		omote_key[3];		//	FM keyondata表
+	int		ura_key[3];			//	FM keyondata裏
+	int		loop_work;			//	Loop Work
+	bool	ppsdrv_flag;		//	ppsdrv を使用するか?flag(ユーザーが代入)
+	int		lastTimerAtime;		//	一個前の割り込み時のTimerATime値
+	int		music_flag;			//	B0:次でMSTART 1:次でMSTOP のFlag
+	int		slotdetune_flag;	//	FM3 Slot Detuneを使っているか
+	int		slot3_flag;			//	FM3 Slot毎 要効果音モードフラグ
+	int		fm3_alg_fb;			//	FM3chの最後に定義した音色のalg/fb
+	int		af_check;			//	FM3chのalg/fbを設定するかしないかflag
+	int		lfo_switch;			//	局所LFOスイッチ
+} PMDWORK;
+
+
+typedef struct effworktag {
+	int		*effadr;			//	effect address
+	int		eswthz;				//	トーンスゥイープ周波数
+	int		eswtst;				//	トーンスゥイープ増分
+	int		effcnt;				//	effect count
+	int		eswnhz;				//	ノイズスゥイープ周波数
+	int		eswnst;				//	ノイズスゥイープ増分
+	int		eswnct;				//	ノイズスゥイープカウント
+	int		effon;				//	効果音 発音中
+	int		psgefcnum;			//	効果音番号
+} EFFWORK;
+
+
+//	演奏中のデータエリア
+typedef struct qqtag {
+	uchar	*address;			//	2 エンソウチュウ ノ アドレス
+	uchar	*partloop;			//	2 エンソウ ガ オワッタトキ ノ モドリサキ
+	int		leng;				//	1 ノコリ LENGTH
+	int		qdat;				//	1 gatetime (q/Q値を計算した値)
+	uint	fnum;				//	2 エンソウチュウ ノ BLOCK/FNUM
+	int		detune;				//	2 デチューン
+	int		lfodat;				//	2 LFO DATA
+	int		porta_num;			//	2 ポルタメントの加減値(全体)
+	int		porta_num2;			//	2 ポルタメントの加減値(一回)
+	int		porta_num3;			//	2 ポルタメントの加減値(余り)
+	int		volume;				//	1 VOLUME
+	int		shift;				//	1 オンカイ シフト ノ アタイ
+	int		delay;				//	1 LFO	[DELAY] 
+	int		speed;				//	1	[SPEED]
+	int		step;				//	1	[STEP]
+	int		time;				//	1	[TIME]
+	int		delay2;				//	1	[DELAY_2]
+	int		speed2;				//	1	[SPEED_2]
+	int		step2;				//	1	[STEP_2]
+	int		time2;				//	1	[TIME_2]
+	int		lfoswi;				//	1 LFOSW. B0/tone B1/vol B2/同期 B3/porta
+								//	         B4/tone B5/vol B6/同期
+	int		volpush;			//	1 Volume PUSHarea
+	int		mdepth;				//	1 M depth
+	int		mdspd;				//	1 M speed
+	int		mdspd2;				//	1 M speed_2
+	int		envf;				//	1 PSG ENV. [START_FLAG] / -1でextend
+	int		eenv_count;			//	1 ExtendPSGenv/No=0 AR=1 DR=2 SR=3 RR=4
+	int		eenv_ar;			//	1 	/AR		/旧pat
+	int		eenv_dr;			//	1	/DR		/旧pv2
+	int		eenv_sr;			//	1	/SR		/旧pr1
+	int		eenv_rr;			//	1	/RR		/旧pr2
+	int		eenv_sl;			//	1	/SL
+	int		eenv_al;			//	1	/AL
+	int		eenv_arc;			//	1	/ARのカウンタ	/旧patb
+	int		eenv_drc;			//	1	/DRのカウンタ
+	int		eenv_src;			//	1	/SRのカウンタ	/旧pr1b
+	int		eenv_rrc;			//	1	/RRのカウンタ	/旧pr2b
+	int		eenv_volume;		//	1	/Volume値(0〜15)/旧penv
+	int		extendmode;			//	1 B1/Detune B2/LFO B3/Env Normal/Extend
+	int		fmpan;				//	1 FM Panning + AMD + PMD
+	int		psgpat;				//	1 PSG PATTERN [TONE/NOISE/MIX]
+	int		voicenum;			//	1 音色番号
+	int		loopcheck;			//	1 ループしたら1 終了したら3
+	int		carrier;			//	1 FM Carrier
+	int		slot1;				//	1 SLOT 1 ノ TL
+	int		slot3;				//	1 SLOT 3 ノ TL
+	int		slot2;				//	1 SLOT 2 ノ TL
+	int		slot4;				//	1 SLOT 4 ノ TL
+	int		slotmask;			//	1 FM slotmask
+	int		neiromask;			//	1 FM 音色定義用maskdata
+	int		lfo_wave;			//	1 LFOの波形
+	int		partmask;			//	1 PartMask b0:通常 b1:効果音 b2:NECPCM用
+								//	   b3:none b4:PPZ/ADE用 b5:s0時 b6:m b7:一時
+	int		keyoff_flag;		//	1 KeyoffしたかどうかのFlag
+	int		volmask;			//	1 音量LFOのマスク
+	int		qdata;				//	1 qの値
+	int		qdatb;				//	1 Qの値
+	int		hldelay;			//	1 HardLFO delay
+	int		hldelay_c;			//	1 HardLFO delay Counter
+	int		_lfodat;			//	2 LFO DATA
+	int		_delay;				//	1 LFO	[DELAY] 
+	int		_speed;				//	1		[SPEED]
+	int		_step;				//	1		[STEP]
+	int		_time;				//	1		[TIME]
+	int		_delay2;			//	1		[DELAY_2]
+	int		_speed2;			//	1		[SPEED_2]
+	int		_step2;				//	1		[STEP_2]
+	int		_time2;				//	1		[TIME_2]
+	int		_mdepth;			//	1 M depth
+	int		_mdspd;				//	1 M speed
+	int		_mdspd2;			//	1 M speed_2
+	int		_lfo_wave;			//	1 LFOの波形
+	int		_volmask;			//	1 音量LFOのマスク
+	int		mdc;				//	1 M depth Counter (変動値)
+	int		mdc2;				//	1 M depth Counter
+	int		_mdc;				//	1 M depth Counter (変動値)
+	int		_mdc2;				//	1 M depth Counter
+	int		onkai;				//	1 演奏中の音階データ (0ffh:rest)
+	int		sdelay;				//	1 Slot delay
+	int		sdelay_c;			//	1 Slot delay counter
+	int		sdelay_m;			//	1 Slot delay Mask
+	int		alg_fb;				//	1 音色のalg/fb
+	int		keyon_flag;			//	1 新音階/休符データを処理したらinc
+	int		qdat2;				//	1 q 最低保証値
+	int		onkai_def;			//	1 演奏中の音階データ (転調処理前 / ?fh:rest)
+	int		shift_def;			//	1 マスター転調値
+	int		qdat3;				//	1 q Random
+} QQ;
+
+
+typedef struct OpenWorktag {
+	QQ *MusPart[NumOfAllPart];	// パートワークのポインタ
+	uchar	*mmlbuf;			//	Musicdataのaddress+1
+	uchar	*tondat;			//	Voicedataのaddress
+	uchar	*efcdat;			//	FM  Effecdataのaddress
+	uchar	*prgdat_adr;		//	曲データ中音色データ先頭番地
+	ushort	*radtbl;			//	R part offset table 先頭番地
+	uchar	*rhyadr;			//	R part 演奏中番地
+	int		rhythmmask;			//	Rhythm音源のマスク x8c/10hのbitに対応
+	int		fm_voldown;			//	FM voldown 数値
+	int		ssg_voldown;		//	PSG voldown 数値
+	int		rhythm_voldown;		//	RHYTHM voldown 数値
+	int		prg_flg;			//	曲データに音色が含まれているかflag
+	int		status;				//	status1
+	int		status2;			//	status2
+	int		tempo_d;			//	tempo (TIMER-B)
+	int		tempo_d_push;		//	tempo (TIMER-B) / 保存用
+	int		syousetu_lng;		//	小節の長さ
+	int		opncount;			//	最短音符カウンタ
+	int		TimerAtime;			//	TimerAカウンタ
+	int		effflag;			//	PSG効果音発声on/off flag(ユーザーが代入)
+	int		psnoi;				//	PSG noise周波数
+	int		psnoi_last;			//	PSG noise周波数(最後に定義した数値)
+	int		rshot_dat;			//	リズム音源 shot flag
+	int		rdat[6];			//	リズム音源 音量/パンデータ
+	int		rhyvol;				//	リズムトータルレベル
+	int		kshot_dat;			//	SSGリズム shot flag
+	int		play_flag;			//	play flag
+	int		slot_detune1;		//	FM3 Slot Detune値 slot1
+	int		slot_detune2;		//	FM3 Slot Detune値 slot2
+	int		slot_detune3;		//	FM3 Slot Detune値 slot3
+	int		slot_detune4;		//	FM3 Slot Detune値 slot4
+	int		TimerB_speed;		//	TimerBの現在値(=ff_tempoならff中)
+	int		syousetu;			//	小節カウンタ
+	int		port22h;			//	OPN-PORT 22H に最後に出力した値(hlfo)
+	int		tempo_48;			//	現在のテンポ(clock=48 tの値)
+	int		tempo_48_push;		//	現在のテンポ(同上/保存用)
+	int		_fm_voldown;		//	FM voldown 数値 (保存用)
+	int		_ssg_voldown;		//	PSG voldown 数値 (保存用)
+	int		_rhythm_voldown;	//	RHYTHM voldown 数値 (保存用)
+	int		ch3mode;			//	ch3 Mode
+	int		TimerAflag;			//	TimerA割り込み中?フラグ(@不要?)
+	int		TimerBflag;			//	TimerB割り込み中?フラグ(@不要?)
+
+	// for PMDWin
+	int		rate;				//	PCM 出力周波数(11k, 22k, 44k, 55k)
+	bool	fmcalc55k;							// FM で 55kHz 合成をするか?
+} OPEN_WORK;
+
+//=============================================================================
+//	PMDWin class
+//=============================================================================
+
+#ifdef __cplusplus
+class PMDWIN
+{
+public:
+	// IPCMMUSICDRIVER
+	bool init(void);
+	int music_load3(uchar *musdata, unsigned int size);
+	void music_start(void);
+	void music_stop(void);
+	int getloopcount(void);
+	bool getlength(uint *length, uint *loop);
+	int getpos(void);
+	void setpos(int pos);
+	void getpcmdata(short *buf, int nsamples);
+    unsigned int getstatus(char *buf, size_t bufsize);
+    void setdevmask(uint8_t mask);
+    void setchanmask(uint32_t mask);
+	
+	// IFMPMD
+    void setpcmrate(unsigned int rate);
+	void setfmcalc55k(bool flag);
+	void setpos2(int pos);
+	int getpos2(void);
+	
+	// IPMDWIN
+	int maskon(unsigned int ch);
+	int maskoff(unsigned int ch);
+	void setfmvoldown(int voldown);
+	void setssgvoldown(int voldown);
+	void setrhythmvoldown(int voldown);
+	int getfmvoldown(void);
+	int getfmvoldown2(void);
+	int getssgvoldown(void);
+	int getssgvoldown2(void);
+	int getrhythmvoldown(void);
+	int getrhythmvoldown2(void);
+	char* _getmemo(char *dest, uchar *musdata, int size, int al);
+	char* _getmemo3(char *dest, uchar *musdata, int size, int al);
+	char* getmemo(char *dest, uchar *musdata, int size, int al);
+	char* getmemo3(char *dest, uchar *musdata, int size, int al);
+	OPEN_WORK* getopenwork(void);
+	QQ* getpartwork(unsigned int ch);
+	
+private:
+	OPNA       opna;
+	
+	OPEN_WORK open_work;
+	QQ FMPart[NumOfFMPart], SSGPart[NumOfSSGPart], RhythmPart;
+	
+	PMDWORK pmdwork;
+	EFFWORK effwork;
+	Stereo16bit	wavbuf2[nbufsample];
+	
+	char	*pos2;						// buf に余っているサンプルの先頭位置
+	int		us2;						// buf に余っているサンプル数
+	uint64_t upos;					    // 演奏開始からの時間(μs)
+	uchar mdataarea[mdata_def*1024];
+	uchar pmdstatus[9];
+
+protected:
+	int uRefCount;		// 参照カウンタ
+	void opnint_start(void);
+	void data_init(void);
+	void opn_init(void);
+	void mstop(void);
+	void mstop_f(void);
+	void silence(void);
+	void mstart(void);
+	void mstart_f(void);
+	void play_init(void);
+	void setint(void);
+	void calc_tb_tempo(void);
+	void calc_tempo_tb(void);
+	void settempo_b(void);
+	void TimerA_main(void);
+	void TimerB_main(void);
+	void mmain(void);
+	void syousetu_count(void);
+	void fmmain(QQ *qq);
+	void psgmain(QQ *qq);
+	void rhythmmain(QQ *qq);
+	uchar *rhythmon(QQ *qq, uchar *bx, int al, int *result);
+	void eff_main(int al);
+	void effplay(void);
+	void efffor(const int *si);
+	void effend(void);
+	void effsweep(void);
+
+	int silence_fmpart(QQ *qq);
+	void keyoff(QQ *qq);
+	void keyoffp(QQ *qq);
+	void kof1(QQ *qq);
+	int ssgdrum_check(QQ *qq, int al);
+    uchar *commands(QQ *qq, uchar *si);
+	uchar *commandsp(QQ *qq, uchar *si);
+	uchar *commandsr(QQ *qq, uchar *si);
+	uchar *special_0c0h(QQ *qq, uchar *si, uchar al);
+	uchar *_vd_fm(QQ *qq, uchar *si);
+	uchar *_vd_ssg(QQ *qq, uchar *si);
+	uchar *_vd_rhythm(QQ *qq, uchar *si);
+	uchar *comt(uchar *si);
+	uchar *comat(QQ *qq, uchar *si);
+	uchar *comatm(QQ *qq, uchar *si);
+	uchar *comstloop(QQ *qq, uchar *si);
+	uchar *comedloop(QQ *qq, uchar *si);
+	uchar *comexloop(QQ *qq, uchar *si);
+	uchar *extend_psgenvset(QQ *qq, uchar *si);
+	void lfoinit(QQ *qq, int al);
+	void lfoinitp(QQ *qq, int al);
+	uchar *lfoset(QQ *qq, uchar *si);
+	uchar *psgenvset(QQ *qq, uchar *si);
+	uchar *rhykey(uchar *si);
+	uchar *rhyvs(uchar *si);
+	uchar *rpnset(uchar *si);
+	uchar *rmsvs(uchar *si);
+	uchar *rmsvs_sft(uchar *si);
+	uchar *rhyvs_sft(uchar *si);
+
+	uchar *vol_one_up_psg(QQ *qq, uchar *si);
+	uchar *vol_one_down(QQ *qq, uchar *si);
+	uchar *portap(QQ *qq, uchar *si);
+	uchar *psgnoise_move(uchar *si);
+	uchar *mdepth_count(QQ *qq, uchar *si);
+	uchar *toneadr_calc(QQ *qq, int dl);
+	void neiroset(QQ *qq, int dl);
+
+	int oshift(QQ *qq, int al);
+	int oshiftp(QQ *qq, int al);
+	void fnumset(QQ *qq, int al);
+	void fnumsetp(QQ *qq, int al);
+	uchar *panset(QQ *qq, uchar *si);
+	uchar *panset_ex(QQ *qq, uchar *si);
+	void panset_main(QQ *qq, int al);
+	uchar calc_panout(QQ *qq);
+	uchar *calc_q(QQ *qq, uchar *si);
+	void fm_block_calc(int *cx, int *ax);
+	int ch3_setting(QQ *qq);
+	void cm_clear(int *ah, int *al);
+	void ch3mode_set(QQ *qq);
+	void ch3_special(QQ *qq, int ax, int cx);
+	void volset(QQ *qq);
+	void volsetp(QQ *qq);
+	void otodasi(QQ *qq);
+	void otodasip(QQ *qq);
+	void keyon(QQ *qq);
+	void keyonp(QQ *qq);
+	int lfo(QQ *qq);
+	uchar *lfoswitch(QQ *qq, uchar *si);
+	void lfoinit_main(QQ *qq);
+	void lfo_change(QQ *qq);
+	void lfo_exit(QQ *qq);
+	void lfin1(QQ *qq);
+	void lfo_main(QQ *qq);
+	void fmlfo_sub(QQ *qq, int al, int bl, uchar *vol_tbl);
+	void volset_slot(int dh, int dl, int al);
+	void porta_calc(QQ *qq);
+    int soft_env(QQ *qq);
+    int soft_env_main(QQ *qq);
+    int soft_env_sub(QQ *qq);
+    int ext_ssgenv_main(QQ *qq);
+    void esm_sub(QQ *qq, int ah);
+	void md_inc(QQ *qq);
+
+	uchar *hlfo_set(QQ *qq, uchar *si);
+	uchar *vol_one_up_fm(QQ *qq, uchar *si);
+	uchar *porta(QQ *qq, uchar *si);
+	uchar *slotmask_set(QQ *qq, uchar *si);
+	uchar *slotdetune_set(QQ *qq, uchar *si);
+	uchar *slotdetune_set2(QQ *qq, uchar *si);
+	uchar *volmask_set(QQ *qq, uchar *si);
+	uchar *fm_mml_part_mask(QQ *qq, uchar *si);
+	uchar *ssg_mml_part_mask(QQ *qq, uchar *si);
+	uchar *rhythm_mml_part_mask(QQ *qq, uchar *si);
+	uchar *_lfoswitch(QQ *qq, uchar *si);
+	uchar *_volmask_set(QQ *qq, uchar *si);
+	uchar *tl_set(QQ *qq, uchar *si);
+	uchar *fb_set(QQ *qq, uchar *si);
+	void neiro_reset(QQ *qq);
+	void swap(int *a, int *b);
+};
+#endif
+
+//============================================================================
+//	DLL Export Functions
+//============================================================================
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
+DLLEXPORT int getversion(void);
+DLLEXPORT bool pmdwininit(void);
+DLLEXPORT void pmdwinfree(void);
+DLLEXPORT void setpcmrate(unsigned int rate);
+DLLEXPORT int music_load3(uchar *musdata, int size);
+DLLEXPORT void music_start(void);
+DLLEXPORT void music_stop(void);
+DLLEXPORT void getpcmdata(short *buf, int nsamples);
+DLLEXPORT void setfmcalc55k(bool flag);
+DLLEXPORT unsigned int getstatus(char *buf, size_t bufsize);
+DLLEXPORT void setdevmask(uint8_t mask);
+DLLEXPORT void setchanmask(uint32_t mask);
+DLLEXPORT char * getmemo(char *dest, uchar *musdata, int size, int al);
+DLLEXPORT char * getmemo3(char *dest, uchar *musdata, int size, int al);
+DLLEXPORT int maskon(unsigned int ch);
+DLLEXPORT int maskoff(unsigned int ch);
+DLLEXPORT void setfmvoldown(int voldown);
+DLLEXPORT void setssgvoldown(int voldown);
+DLLEXPORT void setrhythmvoldown(int voldown);
+DLLEXPORT int getfmvoldown(void);
+DLLEXPORT int getfmvoldown2(void);
+DLLEXPORT int getssgvoldown(void);
+DLLEXPORT int getssgvoldown2(void);
+DLLEXPORT int getrhythmvoldown(void);
+DLLEXPORT int getrhythmvoldown2(void);
+DLLEXPORT void setpos(int pos);
+DLLEXPORT void setpos2(int pos);
+DLLEXPORT int getpos(void);
+DLLEXPORT int getpos2(void);
+DLLEXPORT bool getlength(uint *length, uint *loop);
+DLLEXPORT int getloopcount(void);
+DLLEXPORT OPEN_WORK * getopenwork(void);
+DLLEXPORT QQ * getpartwork(unsigned int ch);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // PMDWIN_H