comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:c55ea9478c80
1 //=============================================================================
2 // Professional Music Driver [P.M.D.] version 4.8
3 // Programmed By M.Kajihara
4 // Windows Converted by C60
5 //=============================================================================
6
7 #ifndef PMDWIN_H
8 #define PMDWIN_H
9
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <limits.h>
13 #include "opna.h"
14
15 typedef unsigned char uchar;
16 typedef unsigned short ushort;
17 typedef unsigned int uint;
18 typedef unsigned long ulong;
19 #ifndef __cplusplus
20 typedef unsigned char bool;
21 #endif
22 extern const int *const efftbl[];
23
24 #ifdef __cplusplus
25 extern "C" {
26 void lfg_srand(unsigned int seed);
27 unsigned int lfg_rand(void);
28 };
29 #endif
30
31
32 //=============================================================================
33 // バージョン情報
34 //=============================================================================
35 #define DLLVersion 36 // 上1桁:major, 下2桁:minor version
36 #define InterfaceVersion 117 // 上1桁:major, 下2桁:minor version
37
38
39 //=============================================================================
40 // DLL の戻り値
41 //=============================================================================
42 #define PMDWIN_OK 0 // 正常終了
43 #define ERR_OPEN_MUSIC_FILE 1 // 曲 データを開けなかった
44 #define ERR_WRONG_MUSIC_FILE 2 // PMD の曲データではなかった
45 #define ERR_WRONG_PARTNO 30 // パート番号が不適
46 //#define ERR_ALREADY_MASKED 31 // 指定パートはすでにマスクされている
47 #define ERR_NOT_MASKED 32 // 指定パートはマスクされていない
48 #define ERR_MUSIC_STOPPED 33 // 曲が止まっているのにマスク操作をした
49 #define ERR_EFFECT_USED 34 // 効果音で使用中なのでマスクを操作できない
50 #define ERR_OUT_OF_MEMORY 99 // メモリを確保できなかった
51 #define ERR_OTHER 999 // その他のエラー
52
53
54 //----------------------------------------------------------------------------
55 // PMDWin専用の定義
56 //----------------------------------------------------------------------------
57 #define SOUND_55K 55555
58 #define SOUND_55K_2 55466
59 #define SOUND_48K 48000
60 #define SOUND_44K 44100
61 #define SOUND_22K 22050
62 #define SOUND_11K 11025
63 #define DEFAULT_REG_WAIT 15000
64 #define MAX_PCMDIR 64
65 #define MAX_MEMOBUF 1024
66
67 //----------------------------------------------------------------------------
68 // その他定義
69 //----------------------------------------------------------------------------
70 //#define nbufsample 30000
71 #define nbufsample 8192
72 #define OPNAClock (3993600*2)
73
74 #define NumOfFMPart 6
75 #define NumOfSSGPart 3
76 #define NumOFOPNARhythmPart 1
77 #define NumOfAllPart (NumOfFMPart+NumOfSSGPart+NumOFOPNARhythmPart)
78
79 #pragma pack( push, enter_include1 )
80 #pragma pack(2)
81
82 typedef struct stereo16bittag
83 {
84 short left;
85 } Stereo16bit;
86
87 #pragma pack( pop, enter_include1 )
88
89 //#define ver "4.8o"
90 //#define vers 0x48
91 //#define verc "o"
92 //#define date "Jun.19th 1997"
93
94 //#define max_part1 22 // 0クリアすべきパート数(for PMDPPZ)
95 #define max_part2 11 // 初期化すべきパート数 (for PMDPPZ)
96
97 #define mdata_def 64
98 #define voice_def 8
99 #define effect_def 64
100
101 #define fmvd_init 0 // 98は88よりもFM音源を小さく
102
103
104 /******************************************************************************
105 ; WORK AREA
106 ******************************************************************************/
107 typedef struct PMDworktag {
108 int partb; // 処理中パート番号
109 int tieflag; // &のフラグ(1 : tie)
110 int volpush_flag; // 次の1音音量down用のflag(1 : voldown)
111 int rhydmy; // R part ダミー演奏データ
112 int fmsel; // FM 表(=0)か裏(=0x100)か flag
113 int omote_key[3]; // FM keyondata表
114 int ura_key[3]; // FM keyondata裏
115 int loop_work; // Loop Work
116 bool ppsdrv_flag; // ppsdrv を使用するか?flag(ユーザーが代入)
117 int lastTimerAtime; // 一個前の割り込み時のTimerATime値
118 int music_flag; // B0:次でMSTART 1:次でMSTOP のFlag
119 int slotdetune_flag; // FM3 Slot Detuneを使っているか
120 int slot3_flag; // FM3 Slot毎 要効果音モードフラグ
121 int fm3_alg_fb; // FM3chの最後に定義した音色のalg/fb
122 int af_check; // FM3chのalg/fbを設定するかしないかflag
123 int lfo_switch; // 局所LFOスイッチ
124 } PMDWORK;
125
126
127 typedef struct effworktag {
128 int *effadr; // effect address
129 int eswthz; // トーンスゥイープ周波数
130 int eswtst; // トーンスゥイープ増分
131 int effcnt; // effect count
132 int eswnhz; // ノイズスゥイープ周波数
133 int eswnst; // ノイズスゥイープ増分
134 int eswnct; // ノイズスゥイープカウント
135 int effon; // 効果音 発音中
136 int psgefcnum; // 効果音番号
137 } EFFWORK;
138
139
140 // 演奏中のデータエリア
141 typedef struct qqtag {
142 uchar *address; // 2 エンソウチュウ ノ アドレス
143 uchar *partloop; // 2 エンソウ ガ オワッタトキ ノ モドリサキ
144 int leng; // 1 ノコリ LENGTH
145 int qdat; // 1 gatetime (q/Q値を計算した値)
146 uint fnum; // 2 エンソウチュウ ノ BLOCK/FNUM
147 int detune; // 2 デチューン
148 int lfodat; // 2 LFO DATA
149 int porta_num; // 2 ポルタメントの加減値(全体)
150 int porta_num2; // 2 ポルタメントの加減値(一回)
151 int porta_num3; // 2 ポルタメントの加減値(余り)
152 int volume; // 1 VOLUME
153 int shift; // 1 オンカイ シフト ノ アタイ
154 int delay; // 1 LFO [DELAY]
155 int speed; // 1 [SPEED]
156 int step; // 1 [STEP]
157 int time; // 1 [TIME]
158 int delay2; // 1 [DELAY_2]
159 int speed2; // 1 [SPEED_2]
160 int step2; // 1 [STEP_2]
161 int time2; // 1 [TIME_2]
162 int lfoswi; // 1 LFOSW. B0/tone B1/vol B2/同期 B3/porta
163 // B4/tone B5/vol B6/同期
164 int volpush; // 1 Volume PUSHarea
165 int mdepth; // 1 M depth
166 int mdspd; // 1 M speed
167 int mdspd2; // 1 M speed_2
168 int envf; // 1 PSG ENV. [START_FLAG] / -1でextend
169 int eenv_count; // 1 ExtendPSGenv/No=0 AR=1 DR=2 SR=3 RR=4
170 int eenv_ar; // 1 /AR /旧pat
171 int eenv_dr; // 1 /DR /旧pv2
172 int eenv_sr; // 1 /SR /旧pr1
173 int eenv_rr; // 1 /RR /旧pr2
174 int eenv_sl; // 1 /SL
175 int eenv_al; // 1 /AL
176 int eenv_arc; // 1 /ARのカウンタ /旧patb
177 int eenv_drc; // 1 /DRのカウンタ
178 int eenv_src; // 1 /SRのカウンタ /旧pr1b
179 int eenv_rrc; // 1 /RRのカウンタ /旧pr2b
180 int eenv_volume; // 1 /Volume値(0〜15)/旧penv
181 int extendmode; // 1 B1/Detune B2/LFO B3/Env Normal/Extend
182 int fmpan; // 1 FM Panning + AMD + PMD
183 int psgpat; // 1 PSG PATTERN [TONE/NOISE/MIX]
184 int voicenum; // 1 音色番号
185 int loopcheck; // 1 ループしたら1 終了したら3
186 int carrier; // 1 FM Carrier
187 int slot1; // 1 SLOT 1 ノ TL
188 int slot3; // 1 SLOT 3 ノ TL
189 int slot2; // 1 SLOT 2 ノ TL
190 int slot4; // 1 SLOT 4 ノ TL
191 int slotmask; // 1 FM slotmask
192 int neiromask; // 1 FM 音色定義用maskdata
193 int lfo_wave; // 1 LFOの波形
194 int partmask; // 1 PartMask b0:通常 b1:効果音 b2:NECPCM用
195 // b3:none b4:PPZ/ADE用 b5:s0時 b6:m b7:一時
196 int keyoff_flag; // 1 KeyoffしたかどうかのFlag
197 int volmask; // 1 音量LFOのマスク
198 int qdata; // 1 qの値
199 int qdatb; // 1 Qの値
200 int hldelay; // 1 HardLFO delay
201 int hldelay_c; // 1 HardLFO delay Counter
202 int _lfodat; // 2 LFO DATA
203 int _delay; // 1 LFO [DELAY]
204 int _speed; // 1 [SPEED]
205 int _step; // 1 [STEP]
206 int _time; // 1 [TIME]
207 int _delay2; // 1 [DELAY_2]
208 int _speed2; // 1 [SPEED_2]
209 int _step2; // 1 [STEP_2]
210 int _time2; // 1 [TIME_2]
211 int _mdepth; // 1 M depth
212 int _mdspd; // 1 M speed
213 int _mdspd2; // 1 M speed_2
214 int _lfo_wave; // 1 LFOの波形
215 int _volmask; // 1 音量LFOのマスク
216 int mdc; // 1 M depth Counter (変動値)
217 int mdc2; // 1 M depth Counter
218 int _mdc; // 1 M depth Counter (変動値)
219 int _mdc2; // 1 M depth Counter
220 int onkai; // 1 演奏中の音階データ (0ffh:rest)
221 int sdelay; // 1 Slot delay
222 int sdelay_c; // 1 Slot delay counter
223 int sdelay_m; // 1 Slot delay Mask
224 int alg_fb; // 1 音色のalg/fb
225 int keyon_flag; // 1 新音階/休符データを処理したらinc
226 int qdat2; // 1 q 最低保証値
227 int onkai_def; // 1 演奏中の音階データ (転調処理前 / ?fh:rest)
228 int shift_def; // 1 マスター転調値
229 int qdat3; // 1 q Random
230 } QQ;
231
232
233 typedef struct OpenWorktag {
234 QQ *MusPart[NumOfAllPart]; // パートワークのポインタ
235 uchar *mmlbuf; // Musicdataのaddress+1
236 uchar *tondat; // Voicedataのaddress
237 uchar *efcdat; // FM Effecdataのaddress
238 uchar *prgdat_adr; // 曲データ中音色データ先頭番地
239 ushort *radtbl; // R part offset table 先頭番地
240 uchar *rhyadr; // R part 演奏中番地
241 int rhythmmask; // Rhythm音源のマスク x8c/10hのbitに対応
242 int fm_voldown; // FM voldown 数値
243 int ssg_voldown; // PSG voldown 数値
244 int rhythm_voldown; // RHYTHM voldown 数値
245 int prg_flg; // 曲データに音色が含まれているかflag
246 int status; // status1
247 int status2; // status2
248 int tempo_d; // tempo (TIMER-B)
249 int tempo_d_push; // tempo (TIMER-B) / 保存用
250 int syousetu_lng; // 小節の長さ
251 int opncount; // 最短音符カウンタ
252 int TimerAtime; // TimerAカウンタ
253 int effflag; // PSG効果音発声on/off flag(ユーザーが代入)
254 int psnoi; // PSG noise周波数
255 int psnoi_last; // PSG noise周波数(最後に定義した数値)
256 int rshot_dat; // リズム音源 shot flag
257 int rdat[6]; // リズム音源 音量/パンデータ
258 int rhyvol; // リズムトータルレベル
259 int kshot_dat; // SSGリズム shot flag
260 int play_flag; // play flag
261 int slot_detune1; // FM3 Slot Detune値 slot1
262 int slot_detune2; // FM3 Slot Detune値 slot2
263 int slot_detune3; // FM3 Slot Detune値 slot3
264 int slot_detune4; // FM3 Slot Detune値 slot4
265 int TimerB_speed; // TimerBの現在値(=ff_tempoならff中)
266 int syousetu; // 小節カウンタ
267 int port22h; // OPN-PORT 22H に最後に出力した値(hlfo)
268 int tempo_48; // 現在のテンポ(clock=48 tの値)
269 int tempo_48_push; // 現在のテンポ(同上/保存用)
270 int _fm_voldown; // FM voldown 数値 (保存用)
271 int _ssg_voldown; // PSG voldown 数値 (保存用)
272 int _rhythm_voldown; // RHYTHM voldown 数値 (保存用)
273 int ch3mode; // ch3 Mode
274 int TimerAflag; // TimerA割り込み中?フラグ(@不要?)
275 int TimerBflag; // TimerB割り込み中?フラグ(@不要?)
276
277 // for PMDWin
278 int rate; // PCM 出力周波数(11k, 22k, 44k, 55k)
279 bool fmcalc55k; // FM で 55kHz 合成をするか?
280 } OPEN_WORK;
281
282 //=============================================================================
283 // PMDWin class
284 //=============================================================================
285
286 #ifdef __cplusplus
287 class PMDWIN
288 {
289 public:
290 // IPCMMUSICDRIVER
291 bool init(void);
292 int music_load3(uchar *musdata, unsigned int size);
293 void music_start(void);
294 void music_stop(void);
295 int getloopcount(void);
296 bool getlength(uint *length, uint *loop);
297 int getpos(void);
298 void setpos(int pos);
299 void getpcmdata(short *buf, int nsamples);
300 unsigned int getstatus(char *buf, size_t bufsize);
301 void setdevmask(uint8_t mask);
302 void setchanmask(uint32_t mask);
303
304 // IFMPMD
305 void setpcmrate(unsigned int rate);
306 void setfmcalc55k(bool flag);
307 void setpos2(int pos);
308 int getpos2(void);
309
310 // IPMDWIN
311 int maskon(unsigned int ch);
312 int maskoff(unsigned int ch);
313 void setfmvoldown(int voldown);
314 void setssgvoldown(int voldown);
315 void setrhythmvoldown(int voldown);
316 int getfmvoldown(void);
317 int getfmvoldown2(void);
318 int getssgvoldown(void);
319 int getssgvoldown2(void);
320 int getrhythmvoldown(void);
321 int getrhythmvoldown2(void);
322 char* _getmemo(char *dest, uchar *musdata, int size, int al);
323 char* _getmemo3(char *dest, uchar *musdata, int size, int al);
324 char* getmemo(char *dest, uchar *musdata, int size, int al);
325 char* getmemo3(char *dest, uchar *musdata, int size, int al);
326 OPEN_WORK* getopenwork(void);
327 QQ* getpartwork(unsigned int ch);
328
329 private:
330 OPNA opna;
331
332 OPEN_WORK open_work;
333 QQ FMPart[NumOfFMPart], SSGPart[NumOfSSGPart], RhythmPart;
334
335 PMDWORK pmdwork;
336 EFFWORK effwork;
337 Stereo16bit wavbuf2[nbufsample];
338
339 char *pos2; // buf に余っているサンプルの先頭位置
340 int us2; // buf に余っているサンプル数
341 uint64_t upos; // 演奏開始からの時間(μs)
342 uchar mdataarea[mdata_def*1024];
343 uchar pmdstatus[9];
344
345 protected:
346 int uRefCount; // 参照カウンタ
347 void opnint_start(void);
348 void data_init(void);
349 void opn_init(void);
350 void mstop(void);
351 void mstop_f(void);
352 void silence(void);
353 void mstart(void);
354 void mstart_f(void);
355 void play_init(void);
356 void setint(void);
357 void calc_tb_tempo(void);
358 void calc_tempo_tb(void);
359 void settempo_b(void);
360 void TimerA_main(void);
361 void TimerB_main(void);
362 void mmain(void);
363 void syousetu_count(void);
364 void fmmain(QQ *qq);
365 void psgmain(QQ *qq);
366 void rhythmmain(QQ *qq);
367 uchar *rhythmon(QQ *qq, uchar *bx, int al, int *result);
368 void eff_main(int al);
369 void effplay(void);
370 void efffor(const int *si);
371 void effend(void);
372 void effsweep(void);
373
374 int silence_fmpart(QQ *qq);
375 void keyoff(QQ *qq);
376 void keyoffp(QQ *qq);
377 void kof1(QQ *qq);
378 int ssgdrum_check(QQ *qq, int al);
379 uchar *commands(QQ *qq, uchar *si);
380 uchar *commandsp(QQ *qq, uchar *si);
381 uchar *commandsr(QQ *qq, uchar *si);
382 uchar *special_0c0h(QQ *qq, uchar *si, uchar al);
383 uchar *_vd_fm(QQ *qq, uchar *si);
384 uchar *_vd_ssg(QQ *qq, uchar *si);
385 uchar *_vd_rhythm(QQ *qq, uchar *si);
386 uchar *comt(uchar *si);
387 uchar *comat(QQ *qq, uchar *si);
388 uchar *comatm(QQ *qq, uchar *si);
389 uchar *comstloop(QQ *qq, uchar *si);
390 uchar *comedloop(QQ *qq, uchar *si);
391 uchar *comexloop(QQ *qq, uchar *si);
392 uchar *extend_psgenvset(QQ *qq, uchar *si);
393 void lfoinit(QQ *qq, int al);
394 void lfoinitp(QQ *qq, int al);
395 uchar *lfoset(QQ *qq, uchar *si);
396 uchar *psgenvset(QQ *qq, uchar *si);
397 uchar *rhykey(uchar *si);
398 uchar *rhyvs(uchar *si);
399 uchar *rpnset(uchar *si);
400 uchar *rmsvs(uchar *si);
401 uchar *rmsvs_sft(uchar *si);
402 uchar *rhyvs_sft(uchar *si);
403
404 uchar *vol_one_up_psg(QQ *qq, uchar *si);
405 uchar *vol_one_down(QQ *qq, uchar *si);
406 uchar *portap(QQ *qq, uchar *si);
407 uchar *psgnoise_move(uchar *si);
408 uchar *mdepth_count(QQ *qq, uchar *si);
409 uchar *toneadr_calc(QQ *qq, int dl);
410 void neiroset(QQ *qq, int dl);
411
412 int oshift(QQ *qq, int al);
413 int oshiftp(QQ *qq, int al);
414 void fnumset(QQ *qq, int al);
415 void fnumsetp(QQ *qq, int al);
416 uchar *panset(QQ *qq, uchar *si);
417 uchar *panset_ex(QQ *qq, uchar *si);
418 void panset_main(QQ *qq, int al);
419 uchar calc_panout(QQ *qq);
420 uchar *calc_q(QQ *qq, uchar *si);
421 void fm_block_calc(int *cx, int *ax);
422 int ch3_setting(QQ *qq);
423 void cm_clear(int *ah, int *al);
424 void ch3mode_set(QQ *qq);
425 void ch3_special(QQ *qq, int ax, int cx);
426 void volset(QQ *qq);
427 void volsetp(QQ *qq);
428 void otodasi(QQ *qq);
429 void otodasip(QQ *qq);
430 void keyon(QQ *qq);
431 void keyonp(QQ *qq);
432 int lfo(QQ *qq);
433 uchar *lfoswitch(QQ *qq, uchar *si);
434 void lfoinit_main(QQ *qq);
435 void lfo_change(QQ *qq);
436 void lfo_exit(QQ *qq);
437 void lfin1(QQ *qq);
438 void lfo_main(QQ *qq);
439 void fmlfo_sub(QQ *qq, int al, int bl, uchar *vol_tbl);
440 void volset_slot(int dh, int dl, int al);
441 void porta_calc(QQ *qq);
442 int soft_env(QQ *qq);
443 int soft_env_main(QQ *qq);
444 int soft_env_sub(QQ *qq);
445 int ext_ssgenv_main(QQ *qq);
446 void esm_sub(QQ *qq, int ah);
447 void md_inc(QQ *qq);
448
449 uchar *hlfo_set(QQ *qq, uchar *si);
450 uchar *vol_one_up_fm(QQ *qq, uchar *si);
451 uchar *porta(QQ *qq, uchar *si);
452 uchar *slotmask_set(QQ *qq, uchar *si);
453 uchar *slotdetune_set(QQ *qq, uchar *si);
454 uchar *slotdetune_set2(QQ *qq, uchar *si);
455 uchar *volmask_set(QQ *qq, uchar *si);
456 uchar *fm_mml_part_mask(QQ *qq, uchar *si);
457 uchar *ssg_mml_part_mask(QQ *qq, uchar *si);
458 uchar *rhythm_mml_part_mask(QQ *qq, uchar *si);
459 uchar *_lfoswitch(QQ *qq, uchar *si);
460 uchar *_volmask_set(QQ *qq, uchar *si);
461 uchar *tl_set(QQ *qq, uchar *si);
462 uchar *fb_set(QQ *qq, uchar *si);
463 void neiro_reset(QQ *qq);
464 void swap(int *a, int *b);
465 };
466 #endif
467
468 //============================================================================
469 // DLL Export Functions
470 //============================================================================
471
472 #ifdef __cplusplus
473 extern "C" {
474 #endif
475
476 #ifdef WIN32
477 #define DLLEXPORT __declspec(dllexport)
478 #else
479 #define DLLEXPORT
480 #endif
481
482 DLLEXPORT int getversion(void);
483 DLLEXPORT bool pmdwininit(void);
484 DLLEXPORT void pmdwinfree(void);
485 DLLEXPORT void setpcmrate(unsigned int rate);
486 DLLEXPORT int music_load3(uchar *musdata, int size);
487 DLLEXPORT void music_start(void);
488 DLLEXPORT void music_stop(void);
489 DLLEXPORT void getpcmdata(short *buf, int nsamples);
490 DLLEXPORT void setfmcalc55k(bool flag);
491 DLLEXPORT unsigned int getstatus(char *buf, size_t bufsize);
492 DLLEXPORT void setdevmask(uint8_t mask);
493 DLLEXPORT void setchanmask(uint32_t mask);
494 DLLEXPORT char * getmemo(char *dest, uchar *musdata, int size, int al);
495 DLLEXPORT char * getmemo3(char *dest, uchar *musdata, int size, int al);
496 DLLEXPORT int maskon(unsigned int ch);
497 DLLEXPORT int maskoff(unsigned int ch);
498 DLLEXPORT void setfmvoldown(int voldown);
499 DLLEXPORT void setssgvoldown(int voldown);
500 DLLEXPORT void setrhythmvoldown(int voldown);
501 DLLEXPORT int getfmvoldown(void);
502 DLLEXPORT int getfmvoldown2(void);
503 DLLEXPORT int getssgvoldown(void);
504 DLLEXPORT int getssgvoldown2(void);
505 DLLEXPORT int getrhythmvoldown(void);
506 DLLEXPORT int getrhythmvoldown2(void);
507 DLLEXPORT void setpos(int pos);
508 DLLEXPORT void setpos2(int pos);
509 DLLEXPORT int getpos(void);
510 DLLEXPORT int getpos2(void);
511 DLLEXPORT bool getlength(uint *length, uint *loop);
512 DLLEXPORT int getloopcount(void);
513 DLLEXPORT OPEN_WORK * getopenwork(void);
514 DLLEXPORT QQ * getpartwork(unsigned int ch);
515
516 #ifdef __cplusplus
517 }
518 #endif
519
520
521 #endif // PMDWIN_H