Mercurial > pmdwin
view 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 source
//============================================================================= // 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