OSDN Git Service

cbd2891eb3389807e2a4a3ea5d1c45d8b793f349
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmgen / opm.h
1 // ---------------------------------------------------------------------------
2 //      OPM-like Sound Generator
3 //      Copyright (C) cisc 1998, 2003.
4 // ---------------------------------------------------------------------------
5 //      $Id: opm.h,v 1.14 2003/06/07 08:25:53 cisc Exp $
6
7 #ifndef FM_OPM_H
8 #define FM_OPM_H
9
10 #include "fmgen.h"
11 #include "fmtimer.h"
12 #include "psg.h"
13
14 class CSP_Logger;
15 // ---------------------------------------------------------------------------
16 //      class OPM
17 //      OPM に良く似た(?)音を生成する音源ユニット
18 //      
19 //      interface:
20 //      bool Init(uint clock, uint rate, bool);
21 //              初期化.このクラスを使用する前にかならず呼んでおくこと.
22 //              注意: 線形補完モードは廃止されました
23 //
24 //              clock:  OPM のクロック周波数(Hz)
25 //
26 //              rate:   生成する PCM の標本周波数(Hz)
27 //
28 //                              
29 //              返値  初期化に成功すれば true
30 //
31 //      bool SetRate(uint clock, uint rate, bool)
32 //              クロックや PCM レートを変更する
33 //              引数等は Init と同様.
34 //      
35 //      void Mix(Sample* dest, int nsamples)
36 //              Stereo PCM データを nsamples 分合成し, dest で始まる配列に
37 //              加える(加算する)
38 //              ・dest には sample*2 個分の領域が必要
39 //              ・格納形式は L, R, L, R... となる.
40 //              ・あくまで加算なので,あらかじめ配列をゼロクリアする必要がある
41 //              ・FM_SAMPLETYPE が short 型の場合クリッピングが行われる.
42 //              ・この関数は音源内部のタイマーとは独立している.
43 //                Timer は Count と GetNextEvent で操作する必要がある.
44 //      
45 //      void Reset()
46 //              音源をリセット(初期化)する
47 //
48 //      void SetReg(uint reg, uint data)
49 //              音源のレジスタ reg に data を書き込む
50 //      
51 //      uint ReadStatus()
52 //              音源のステータスレジスタを読み出す
53 //              busy フラグは常に 0
54 //      
55 //      bool ReadIRQ()
56 //              IRQ 出力を読み出す
57 //      
58 //      bool Count(uint32 t)
59 //              音源のタイマーを t [clock] 進める.
60 //              音源の内部状態に変化があった時(timer オーバーフロー)
61 //              true を返す
62 //
63 //      uint32 GetNextEvent()
64 //              音源のタイマーのどちらかがオーバーフローするまでに必要な
65 //              時間[clock]を返す
66 //              タイマーが停止している場合は 0 を返す.
67 //      
68 //      void SetVolume(int db_l, int db_r)
69 //              各音源の音量を+−方向に調節する.標準値は 0.
70 //              単位は約 1/2 dB,有効範囲の上限は 20 (10dB)
71 //
72 namespace FM
73 {
74         //      YM2151(OPM) ----------------------------------------------------
75         class DLL_PREFIX  OPM : public Timer
76         {
77         protected:
78                 int chip_num;
79         public:
80                 OPM();
81                 ~OPM() {}
82
83                 bool    Init(uint c, uint r, bool=false);
84                 bool    SetRate(uint c, uint r, bool);
85                 void    SetLPFCutoff(uint freq);
86                 void    Reset();
87                 bool    ReadIRQ();
88                 
89                 void    SetReg(uint addr, uint data);
90                 uint    GetReg(uint addr);
91                 uint    ReadStatus() { return status & 0x03; }
92                 
93                 void    Mix(Sample* buffer, int nsamples);
94                 
95                 void    SetVolume(int db_l, int db_r);
96                 void    SetChannelMask(uint mask);
97
98                 bool    ProcessState(void *f, bool loading);
99                 
100         private:
101                 void    Intr(bool value);
102         
103         private:
104                 enum
105                 {
106                         OPM_LFOENTS = 512,
107                 };
108                 
109                 void    SetStatus(uint bit);
110                 void    ResetStatus(uint bit);
111                 void    SetParameter(uint addr, uint data);
112                 void    TimerA();
113                 void    RebuildTimeTable();
114                 void    MixSub(int activech, ISample**);
115                 void    MixSubL(int activech, ISample**);
116                 void    LFO();
117                 uint    Noise();
118                 
119                 int             fmvolume_l;
120                 int             fmvolume_r;
121
122                 uint    clock;
123                 uint    rate;
124                 uint    pcmrate;
125
126                 uint    pmd;
127                 uint    amd;
128                 uint    lfocount;
129                 uint    lfodcount;
130
131                 uint    lfo_count_;
132                 uint    lfo_count_diff_;
133                 uint    lfo_step_;
134                 uint    lfo_count_prev_;
135
136                 uint    lfowaveform;
137                 uint    rateratio;
138                 uint    noise;
139                 int32   noisecount;
140                 uint32  noisedelta;
141                 
142                 bool    interpolation;
143                 uint8   lfofreq;
144                 uint8   status;
145                 bool    interrupt;
146                 uint8   reg01;
147
148                 uint8   kc[8];
149                 uint8   kf[8];
150                 uint8   pan[8];
151
152                 Channel4 ch[8];
153                 Chip    chip;
154
155                 static void     BuildLFOTable();
156                 static int amtable[4][OPM_LFOENTS];
157                 static int pmtable[4][OPM_LFOENTS];
158
159         public:
160                 int             dbgGetOpOut(int c, int s) { return ch[c].op[s].dbgopout_; }
161                 Channel4* dbgGetCh(int c) { return &ch[c]; }
162
163         };
164 }
165
166 #endif // FM_OPM_H