OSDN Git Service

[VM][General] Merge Upstream 2017-12-15.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmgen / fmgen.cpp
1 // ---------------------------------------------------------------------------
2 //      FM Sound Generator - Core Unit
3 //      Copyright (C) cisc 1998, 2003.
4 // ---------------------------------------------------------------------------
5 //      $Id: fmgen.cpp,v 1.50 2003/09/10 13:19:34 cisc Exp $
6 // ---------------------------------------------------------------------------
7 //      \8eQ\8dl:
8 //              FM sound generator for M.A.M.E., written by Tatsuyuki Satoh.
9 //
10 //      \93ä:
11 //              OPNB \82Ì CSM \83\82\81[\83h(\8ed\97l\82ª\82æ\82­\82í\82©\82ç\82È\82¢)
12 //
13 //      \90§\8cÀ:
14 //              \81EAR!=31 \82Å SSGEC \82ð\8eg\82¤\82Æ\94g\8c`\82ª\8eÀ\8dÛ\82Æ\88Ù\82È\82é\89Â\94\\90«\82 \82è
15 //
16 //      \8eÓ\8e«:
17 //              Tatsuyuki Satoh \82³\82ñ(fm.c)
18 //              Hiromitsu Shioya \82³\82ñ(ADPCM-A)
19 //              DMP-SOFT. \82³\82ñ(OPNB)
20 //              KAJA \82³\82ñ(test program)
21 //              \82Ù\82©\8cf\8e¦\94Â\93\99\82Å\97l\81X\82È\82²\8f\95\8c¾\81C\82²\8ex\89\87\82ð\82¨\8añ\82¹\82¢\82½\82¾\82¢\82½\8aF\97l\82É
22 // ---------------------------------------------------------------------------
23
24 #include "headers.h"
25 #include "misc.h"
26 #include "fmgen.h"
27 #include "fmgeninl.h"
28
29 #include "../../fileio.h"
30
31 #define LOGNAME "fmgen"
32
33 // ---------------------------------------------------------------------------
34
35 #define FM_EG_BOTTOM 955
36
37 // ---------------------------------------------------------------------------
38 //      Table/etc
39 //
40 namespace FM
41 {
42         const uint8 Operator::notetable[128] =
43         {
44                  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  3,  3,  3,  3,  3,  3, 
45                  4,  4,  4,  4,  4,  4,  4,  5,  6,  7,  7,  7,  7,  7,  7,  7, 
46                  8,  8,  8,  8,  8,  8,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11, 
47                 12, 12, 12, 12, 12, 12, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 
48                 16, 16, 16, 16, 16, 16, 16, 17, 18, 19, 19, 19, 19, 19, 19, 19, 
49                 20, 20, 20, 20, 20, 20, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 
50                 24, 24, 24, 24, 24, 24, 24, 25, 26, 27, 27, 27, 27, 27, 27, 27, 
51                 28, 28, 28, 28, 28, 28, 28, 29, 30, 31, 31, 31, 31, 31, 31, 31, 
52         };
53         
54         const int8 Operator::dttable[256] =
55         {
56                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
57                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
58                   0,  0,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  4,  4,  4,  4,
59                   4,  6,  6,  6,  8,  8,  8, 10, 10, 12, 12, 14, 16, 16, 16, 16,
60                   2,  2,  2,  2,  4,  4,  4,  4,  4,  6,  6,  6,  8,  8,  8, 10,
61                  10, 12, 12, 14, 16, 16, 18, 20, 22, 24, 26, 28, 32, 32, 32, 32,
62                   4,  4,  4,  4,  4,  6,  6,  6,  8,  8,  8, 10, 10, 12, 12, 14,
63                  16, 16, 18, 20, 22, 24, 26, 28, 32, 34, 38, 40, 44, 44, 44, 44,
64                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
65                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
66                   0,  0,  0,  0, -2, -2, -2, -2, -2, -2, -2, -2, -4, -4, -4, -4,
67                  -4, -6, -6, -6, -8, -8, -8,-10,-10,-12,-12,-14,-16,-16,-16,-16,
68                  -2, -2, -2, -2, -4, -4, -4, -4, -4, -6, -6, -6, -8, -8, -8,-10,
69                 -10,-12,-12,-14,-16,-16,-18,-20,-22,-24,-26,-28,-32,-32,-32,-32,
70                  -4, -4, -4, -4, -4, -6, -6, -6, -8, -8, -8,-10,-10,-12,-12,-14,
71                 -16,-16,-18,-20,-22,-24,-26,-28,-32,-34,-38,-40,-44,-44,-44,-44,
72         };
73
74         const int8 Operator::decaytable1[64][8] = 
75         {
76                 0, 0, 0, 0, 0, 0, 0, 0,         0, 0, 0, 0, 0, 0, 0, 0,
77                 1, 1, 1, 1, 1, 1, 1, 1,         1, 1, 1, 1, 1, 1, 1, 1,
78                 1, 1, 1, 1, 1, 1, 1, 1,         1, 1, 1, 1, 1, 1, 1, 1,
79                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 0, 1, 1, 1, 0,
80                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
81                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
82                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
83                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
84                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
85                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
86                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
87                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
88                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
89                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
90                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
91                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
92                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
93                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
94                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
95                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
96                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
97                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
98                 1, 0, 1, 0, 1, 0, 1, 0,         1, 1, 1, 0, 1, 0, 1, 0,
99                 1, 1, 1, 0, 1, 1, 1, 0,         1, 1, 1, 1, 1, 1, 1, 0,
100                 1, 1, 1, 1, 1, 1, 1, 1,         2, 1, 1, 1, 2, 1, 1, 1,
101                 2, 1, 2, 1, 2, 1, 2, 1,         2, 2, 2, 1, 2, 2, 2, 1,
102                 2, 2, 2, 2, 2, 2, 2, 2,         4, 2, 2, 2, 4, 2, 2, 2, 
103                 4, 2, 4, 2, 4, 2, 4, 2,         4, 4, 4, 2, 4, 4, 4, 2,
104                 4, 4, 4, 4, 4, 4, 4, 4,         8, 4, 4, 4, 8, 4, 4, 4, 
105                 8, 4, 8, 4, 8, 4, 8, 4,         8, 8, 8, 4, 8, 8, 8, 4,
106                 16,16,16,16,16,16,16,16,        16,16,16,16,16,16,16,16,
107                 16,16,16,16,16,16,16,16,        16,16,16,16,16,16,16,16,
108         };
109
110         const int Operator::decaytable2[16] = 
111         {
112                 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2047, 2047, 2047, 2047, 2047
113         };
114
115         const int8 Operator::attacktable[64][8] = 
116         {
117                 -1,-1,-1,-1,-1,-1,-1,-1,        -1,-1,-1,-1,-1,-1,-1,-1,
118                  4, 4, 4, 4, 4, 4, 4, 4,         4, 4, 4, 4, 4, 4, 4, 4,
119                  4, 4, 4, 4, 4, 4, 4, 4,         4, 4, 4, 4, 4, 4, 4, 4,
120                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4,-1, 4, 4, 4,-1,
121                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
122                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
123                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
124                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
125                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
126                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
127                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
128                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
129                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
130                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
131                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
132                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
133                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
134                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
135                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
136                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
137                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
138                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
139                  4,-1, 4,-1, 4,-1, 4,-1,         4, 4, 4,-1, 4,-1, 4,-1,
140                  4, 4, 4,-1, 4, 4, 4,-1,         4, 4, 4, 4, 4, 4, 4,-1,
141                  4, 4, 4, 4, 4, 4, 4, 4,         3, 4, 4, 4, 3, 4, 4, 4,
142                  3, 4, 3, 4, 3, 4, 3, 4,         3, 3, 3, 4, 3, 3, 3, 4,
143                  3, 3, 3, 3, 3, 3, 3, 3,         2, 3, 3, 3, 2, 3, 3, 3,
144                  2, 3, 2, 3, 2, 3, 2, 3,         2, 2, 2, 3, 2, 2, 2, 3,
145                  2, 2, 2, 2, 2, 2, 2, 2,         1, 2, 2, 2, 1, 2, 2, 2,
146                  1, 2, 1, 2, 1, 2, 1, 2,         1, 1, 1, 2, 1, 1, 1, 2,
147                  0, 0, 0, 0, 0, 0, 0, 0,         0, 0 ,0, 0, 0, 0, 0, 0,
148                  0, 0, 0, 0, 0, 0, 0, 0,         0, 0 ,0, 0, 0, 0, 0, 0,
149         };
150
151         const int Operator::ssgenvtable[8][2][3][2] =
152         {
153                 1, 1,  1, 1,  1, 1,             // 08 
154                 0, 1,  1, 1,  1, 1,             // 08 56~
155                 0, 1,  2, 0,  2, 0,             // 09
156                 0, 1,  2, 0,  2, 0,             // 09
157                 1,-1,  0, 1,  1,-1,             // 10
158                 0, 1,  1,-1,  0, 1,             // 10 60~
159                 1,-1,  0, 0,  0, 0,             // 11
160                 0, 1,  0, 0,  0, 0,             // 11 60~
161                 2,-1,  2,-1,  2,-1,             // 12
162                 1,-1,  2,-1,  2,-1,             // 12 56~
163                 1,-1,  0, 0,  0, 0,             // 13
164                 1,-1,  0, 0,  0, 0,             // 13
165                 0, 1,  1,-1,  0, 1,             // 14
166                 1,-1,  0, 1,  1,-1,             // 14 60~
167                 0, 1,  2, 0,  2, 0,             // 15
168                 1,-1,  2, 0,  2, 0,             // 15 60~
169         };
170
171         // fixed equasion-based tables
172         int             pmtable[2][8][FM_LFOENTS];
173         uint    volatile  amtable[2][4][FM_LFOENTS];
174
175         static bool tablemade = false;
176 }
177
178 namespace FM
179 {
180
181 // ---------------------------------------------------------------------------
182 //      \83e\81[\83u\83\8b\8dì\90¬
183 //
184 void MakeLFOTable()
185 {
186         if (tablemade)
187                 return;
188
189         tablemade = true;
190         
191         int i;
192
193         static const double pms[2][8] = 
194         { 
195                 { 0, 1/360., 2/360., 3/360.,  4/360.,  6/360., 12/360.,  24/360., },    // OPNA
196 //              { 0, 1/240., 2/240., 4/240., 10/240., 20/240., 80/240., 140/240., },    // OPM
197                 { 0, 1/480., 2/480., 4/480., 10/480., 20/480., 80/480., 140/480., },    // OPM
198 //              { 0, 1/960., 2/960., 4/960., 10/960., 20/960., 80/960., 140/960., },    // OPM
199         };
200         //               3               6,      12      30       60       240      420         / 720
201         //      1.000963
202         //      lfofref[level * max * wave];
203         //      pre = lfofref[level][pms * wave >> 8];
204         static const volatile uint8 amt[2][4] = 
205         {
206                 { 31, 6, 4, 3 }, // OPNA
207                 { 31, 2, 1, 0 }, //     OPM
208         };
209         
210         for (int type = 0; type < 2; type++)
211         {
212                 for (i=0; i<8; i++)
213                 {
214                         double pmb = pms[type][i];
215                         for (int j=0; j<FM_LFOENTS; j++)
216                         {
217 //                              double v = pow(2.0, pmb * (2 * j - FM_LFOENTS+1) / (FM_LFOENTS-1));
218                                 double w = 0.6 * pmb * sin(2 * j * 3.14159265358979323846 / FM_LFOENTS) + 1;
219 //                              pmtable[type][i][j] = int(0x10000 * (v - 1));
220 //                              if (type == 0)
221                                         pmtable[type][i][j] = int(0x10000 * (w - 1));
222 //                              else
223 //                                      pmtable[type][i][j] = int(0x10000 * (v - 1));
224
225 //                              printf("pmtable[%d][%d][%.2x] = %5d  %7.5f %7.5f\n", type, i, j, pmtable[type][i][j], v, w);
226                         }
227                 }
228                 for (i=0; i<4; i++)
229                 {
230                         for (int j=0; j<FM_LFOENTS; j++)
231                         {
232                                 amtable[type][i][j] = (((j * 4) >> amt[type][i]) * 2) << 2;
233                         }
234                 }
235         }
236 }
237
238
239 // ---------------------------------------------------------------------------
240 //      \83`\83b\83v\93à\82Å\8b¤\92Ê\82È\95\94\95ª
241 //
242 Chip::Chip()
243 : ratio_(0), aml_(0), pml_(0), pmv_(0), optype_(typeN)
244 {
245 }
246
247 //      \83N\83\8d\83b\83N\81E\83T\83\93\83v\83\8a\83\93\83O\83\8c\81[\83g\94ä\82É\88Ë\91\82·\82é\83e\81[\83u\83\8b\82ð\8dì\90¬
248 void Chip::SetRatio(uint ratio)
249 {
250         if (ratio_ != ratio)
251         {
252                 ratio_ = ratio;
253                 MakeTable();
254         }
255 }
256
257 void Chip::MakeTable()
258 {
259         int h, l;
260         
261         // PG Part
262         static const float dt2lv[4] = { 1.f, 1.414f, 1.581f, 1.732f };
263         for (h=0; h<4; h++)
264         {
265                 assert(2 + FM_RATIOBITS - FM_PGBITS >= 0);
266                 double rr = dt2lv[h] * double(ratio_);
267                 for (l=0; l<16; l++)
268                 {
269                         int mul = l ? l * 2 : 1;
270                         multable_[h][l] = uint(mul * rr);
271                 }
272         }
273 }
274
275 // ---------------------------------------------------------------------------
276 //      \83X\83e\81[\83g\83Z\81[\83u
277 //
278 #define CHIP_STATE_VERSION      1
279
280 void Chip::SaveState(void *f)
281 {
282         FILEIO *state_fio = (FILEIO *)f;
283         
284         state_fio->FputUint32(CHIP_STATE_VERSION);
285         
286         state_fio->FputUint32(ratio_);
287         state_fio->FputUint32(aml_);
288         state_fio->FputUint32(pml_);
289         state_fio->FputInt32(pmv_);
290 }
291
292 bool Chip::LoadState(void *f)
293 {
294         FILEIO *state_fio = (FILEIO *)f;
295         
296         if(state_fio->FgetUint32() != CHIP_STATE_VERSION) {
297                 return false;
298         }
299         ratio_ = state_fio->FgetUint32();
300         aml_ = state_fio->FgetUint32();
301         pml_ = state_fio->FgetUint32();
302         pmv_ = state_fio->FgetInt32();
303         return true;
304 }
305
306
307 // ---------------------------------------------------------------------------
308 //      Operator
309 //
310 bool FM::Operator::tablehasmade = false;
311 uint FM::Operator::sinetable[1024];
312 int32 FM::Operator::cltable[FM_CLENTS];
313
314 //      \8d\\92z
315 FM::Operator::Operator()
316 : chip_(0)
317 {
318         if (!tablehasmade)
319                 MakeTable();
320
321         // EG Part
322         ar_ = dr_ = sr_ = rr_ = key_scale_rate_ = 0;
323         ams_ = amtable[0][0];
324         mute_ = false;
325         keyon_ = false;
326         tl_out_ = false;
327         ssg_type_ = 0;
328
329         // PG Part
330         multiple_ = 0;
331         detune_ = 0;
332         detune2_ = 0;
333
334         // LFO
335         ms_ = 0;
336         
337 //      Reset();
338 }
339
340 //      \8f\89\8aú\89»
341 void FM::Operator::Reset()
342 {
343         // EG part
344         tl_ = tl_latch_ = 127;
345         ShiftPhase(off);
346         eg_count_ = 0;
347         eg_curve_count_ = 0;
348         ssg_phase_ = 0;
349
350         // PG part
351         pg_count_ = 0;
352
353         // OP part
354         out_ = out2_ = 0;
355
356         param_changed_ = true;
357         PARAMCHANGE(0);
358 }
359
360 void Operator::MakeTable()
361 {
362         // \91Î\90\94\83e\81[\83u\83\8b\82Ì\8dì\90¬
363         assert(FM_CLENTS >= 256);
364
365         int* p = cltable;
366         int i;
367         for (i=0; i<256; i++)
368         {
369                 int v = int(floor(pow(2., 13. - i / 256.)));
370                 v = (v + 2) & ~3;
371                 *p++ = v;
372                 *p++ = -v;
373         }
374         while (p < cltable + FM_CLENTS)
375         {
376                 *p = p[-512] / 2;
377                 p++;
378         }
379
380 //      for (i=0; i<13*256; i++)
381 //              printf("%4d, %d, %d\n", i, cltable[i*2], cltable[i*2+1]);
382
383         // \83T\83C\83\93\83e\81[\83u\83\8b\82Ì\8dì\90¬
384         double log2 = log(2.);
385         for (i=0; i<FM_OPSINENTS/2; i++)
386         {
387                 double r = (i * 2 + 1) * FM_PI / FM_OPSINENTS;
388                 double q = -256 * log(sin(r)) / log2;
389                 uint s = (int) (floor(q + 0.5)) + 1;
390 //              printf("%d, %d\n", s, cltable[s * 2] / 8);
391                 sinetable[i]                  = s * 2 ;
392                 sinetable[FM_OPSINENTS / 2 + i] = s * 2 + 1;
393         }
394
395         ::FM::MakeLFOTable();
396
397         tablehasmade = true;
398 }
399
400
401
402 inline void FM::Operator::SetDPBN(uint dp, uint bn)
403 {
404         dp_ = dp, bn_ = bn; param_changed_ = true; 
405         PARAMCHANGE(1);
406 }
407
408
409 //      \8f\80\94õ
410 void Operator::Prepare()
411 {
412         if (param_changed_)
413         {
414                 param_changed_ = false;
415                 //      PG Part
416                 pg_diff_ = (dp_ + dttable[detune_ + bn_]) * chip_->GetMulValue(detune2_, multiple_);
417                 pg_diff_ >>= (2 + FM_RATIOBITS - FM_PGBITS);
418                 pg_diff_lfo_ = pg_diff_ >> 11;
419
420                 // EG Part
421                 key_scale_rate_ = bn_ >> (3-ks_);
422                 tl_out_ = mute_ ? 0x3ff : tl_ * 8;
423                 
424                 switch (eg_phase_)
425                 {
426                 case attack:
427                         SetEGRate(ar_ ? Min(63, ar_ + key_scale_rate_) : 0);
428                         break;
429                 case decay:
430                         SetEGRate(dr_ ? Min(63, dr_ + key_scale_rate_) : 0);
431                         eg_level_on_next_phase_ = sl_ * 8;
432                         break;
433                 case sustain:
434                         SetEGRate(sr_ ? Min(63, sr_ + key_scale_rate_) : 0);
435                         break;
436                 case release:
437                         SetEGRate(Min(63, rr_ + key_scale_rate_));
438                         break;
439                 }
440
441                 // SSG-EG
442                 if (ssg_type_ && (eg_phase_ != release))
443                 {
444                         int m = ar_ >= (uint)((ssg_type_ == 8 || ssg_type_ == 12) ? 56 : 60);
445
446                         if (ssg_phase_ == -1)           // XXX quick fix
447                                 ssg_phase_ = 0;
448                         assert(0 <= ssg_phase_ && ssg_phase_ <= 2);
449                         const int* table = ssgenvtable[ssg_type_ & 7][m][ssg_phase_];
450
451                         ssg_offset_ = table[0] * 0x200;
452                         ssg_vector_ = table[1];
453                 }
454                 // LFO
455                 ams_ = amtable[type_][amon_ ? (ms_ >> 4) & 3 : 0];
456                 EGUpdate();
457
458                 dbgopout_ = 0;
459         }
460 }
461 //      envelop \82Ì eg_phase_ \95Ï\8dX
462 void Operator::ShiftPhase(EGPhase nextphase)
463 {
464         switch (nextphase)
465         {
466         case attack:            // Attack Phase
467                 tl_ = tl_latch_;
468                 if (ssg_type_)
469                 {
470                         ssg_phase_ = ssg_phase_ + 1;
471                         if (ssg_phase_ > 2)
472                                 ssg_phase_ = 1;
473                         
474                         int m = ar_ >= (uint)((ssg_type_ == 8 || ssg_type_ == 12) ? 56 : 60);
475
476                         assert(0 <= ssg_phase_ && ssg_phase_ <= 2);
477                         const int* table = ssgenvtable[ssg_type_ & 7][m][ssg_phase_];
478
479                         ssg_offset_ = table[0] * 0x200;
480                         ssg_vector_ = table[1];
481                 }
482                 if ((ar_ + key_scale_rate_) < 62)
483                 {
484                         SetEGRate(ar_ ? Min(63, ar_ + key_scale_rate_) : 0);
485                         eg_phase_ = attack;
486                         break;
487                 }
488         case decay:                     // Decay Phase
489                 if (sl_)
490                 {
491                         eg_level_ = 0;
492                         eg_level_on_next_phase_ = ssg_type_ ? Min(sl_ * 8, 0x200) : sl_ * 8;
493
494                         SetEGRate(dr_ ? Min(63, dr_ + key_scale_rate_) : 0);
495                         eg_phase_ = decay;
496                         break;
497                 }
498         case sustain:           // Sustain Phase
499                 eg_level_ = sl_ * 8;
500                 eg_level_on_next_phase_ = ssg_type_ ? 0x200 : 0x400;
501
502                 SetEGRate(sr_ ? Min(63, sr_ + key_scale_rate_) : 0);
503                 eg_phase_ = sustain;
504                 break;
505         
506         case release:           // Release Phase
507                 if (ssg_type_)
508                 {
509                         eg_level_ = eg_level_ * ssg_vector_ + ssg_offset_;
510                         ssg_vector_ = 1;
511                         ssg_offset_ = 0;
512                 }
513                 if (eg_phase_ == attack || (eg_level_ < FM_EG_BOTTOM)) //0x400/* && eg_phase_ != off*/))
514                 {
515                         eg_level_on_next_phase_ = 0x400;
516                         SetEGRate(Min(63, rr_ + key_scale_rate_));
517                         eg_phase_ = release;
518                         break;
519                 }
520         case off:                       // off
521         default:
522                 eg_level_ = FM_EG_BOTTOM;
523                 eg_level_on_next_phase_ = FM_EG_BOTTOM;
524                 EGUpdate();
525                 SetEGRate(0);
526                 eg_phase_ = off;
527                 break;
528         }
529 }
530
531 //      Block/F-Num
532 void Operator::SetFNum(uint f)
533 {
534         dp_ = (f & 2047) << ((f >> 11) & 7);
535         bn_ = notetable[(f >> 7) & 127];
536         param_changed_ = true;
537         PARAMCHANGE(2);
538 }
539
540 //      \82P\83T\83\93\83v\83\8b\8d\87\90¬
541
542 //      ISample \82ð envelop count (2\83Î) \82É\95Ï\8a·\82·\82é\83V\83t\83g\97Ê
543 #define IS2EC_SHIFT             ((20 + FM_PGBITS) - 13)
544
545
546 // \93ü\97Í: s = 20+FM_PGBITS = 29
547 #define Sine(s) sinetable[((s) >> (20+FM_PGBITS-FM_OPSINBITS))&(FM_OPSINENTS-1)]
548 #define SINE(s) sinetable[(s) & (FM_OPSINENTS-1)]
549
550 inline FM::ISample Operator::LogToLin(uint a)
551 {
552 #if 1 // FM_CLENTS < 0xc00              // 400 for TL, 400 for ENV, 400 for LFO.
553         return (a < FM_CLENTS) ? cltable[a] : 0;
554 #else
555         return cltable[a];
556 #endif
557 }
558
559 inline void Operator::EGUpdate()
560 {
561         if (!ssg_type_)
562         {
563                 eg_out_ = Min(tl_out_ + eg_level_, 0x3ff) << (1 + 2);
564         }
565         else
566         {
567                 eg_out_ = Min(tl_out_ + eg_level_ * ssg_vector_ + ssg_offset_, 0x3ff) << (1 + 2);
568         }
569 }
570
571 inline void Operator::SetEGRate(uint rate)
572 {
573         eg_rate_ = rate;
574         eg_count_diff_ = decaytable2[rate / 4] * chip_->GetRatio();
575 }
576
577 //      EG \8cv\8eZ
578 void FM::Operator::EGCalc()
579 {
580         eg_count_ = (2047 * 3) << FM_RATIOBITS;                         // ##\82±\82Ì\8eè\94²\82«\82Í\8dÄ\8c»\90«\82ð\92á\89º\82³\82¹\82é
581         
582         if (eg_phase_ == attack)
583         {
584                 int c = attacktable[eg_rate_][eg_curve_count_ & 7];
585                 if (c >= 0)
586                 {
587                         eg_level_ -= 1 + (eg_level_ >> c);
588                         if (eg_level_ <= 0)
589                                 ShiftPhase(decay);
590                 }
591                 EGUpdate();
592         }
593         else
594         {
595                 if (!ssg_type_)
596                 {
597                         eg_level_ += decaytable1[eg_rate_][eg_curve_count_ & 7];
598                         if (eg_level_ >= eg_level_on_next_phase_)
599                                 ShiftPhase(EGPhase(eg_phase_+1));
600                         EGUpdate();
601                 }
602                 else
603                 {
604                         eg_level_ += 4 * decaytable1[eg_rate_][eg_curve_count_ & 7];
605                         if (eg_level_ >= eg_level_on_next_phase_)
606                         {
607                                 switch (eg_phase_)
608                                 {
609                                 case decay:
610                                         ShiftPhase(sustain);
611                                         break;
612                                 case sustain:
613                                         ShiftPhase(attack);
614                                         break;
615                                 case release:
616                                         ShiftPhase(off);
617                                         break;
618                                 }
619                         }
620                         EGUpdate();
621                 }
622         }
623         eg_curve_count_++;
624 }
625
626 inline void FM::Operator::EGStep()
627 {
628         eg_count_ -= eg_count_diff_;
629
630         // EG \82Ì\95Ï\89»\82Í\91S\83X\83\8d\83b\83g\82Å\93¯\8aú\82µ\82Ä\82¢\82é\82Æ\82¢\82¤\89\\82à\82 \82é
631         if (eg_count_ <= 0)
632                 EGCalc();
633 }
634
635 //      PG \8cv\8eZ
636 //      ret:2^(20+PGBITS) / cycle
637 inline uint32 FM::Operator::PGCalc()
638 {
639         uint32 ret = pg_count_;
640         pg_count_ += pg_diff_;
641         dbgpgout_ = ret;
642         return ret;
643 }
644
645 inline uint32 FM::Operator::PGCalcL()
646 {
647         uint32 ret = pg_count_;
648         pg_count_ += pg_diff_ + ((pg_diff_lfo_ * chip_->GetPMV()) >> 5);// & -(1 << (2+IS2EC_SHIFT)));
649         dbgpgout_ = ret;
650         return ret /* + pmv * pg_diff_;*/;
651 }
652
653 //      OP \8cv\8eZ
654 //      in: ISample (\8dÅ\91å 8\83Î)
655 inline FM::ISample FM::Operator::Calc(ISample in)
656 {
657         EGStep();
658         out2_ = out_;
659
660         int pgin = PGCalc() >> (20+FM_PGBITS-FM_OPSINBITS);
661         pgin += in >> (20+FM_PGBITS-FM_OPSINBITS-(2+IS2EC_SHIFT));
662         out_ = LogToLin(eg_out_ + SINE(pgin));
663
664         dbgopout_ = out_;
665         return out_;
666 }
667
668 inline FM::ISample FM::Operator::CalcL(ISample in)
669 {
670         EGStep();
671
672         int pgin = PGCalcL() >> (20+FM_PGBITS-FM_OPSINBITS);
673         pgin += in >> (20+FM_PGBITS-FM_OPSINBITS-(2+IS2EC_SHIFT));
674         out_ = LogToLin(eg_out_ + SINE(pgin) + ams_[chip_->GetAML()]);
675
676         dbgopout_ = out_;
677         return out_;
678 }
679
680 inline FM::ISample FM::Operator::CalcN(uint noise)
681 {
682         EGStep();
683         
684         int lv = Max(0, 0x3ff - (tl_out_ + eg_level_)) << 1;
685         
686         // noise & 1 ? lv : -lv \82Æ\93\99\89¿ 
687         noise = (noise & 1) - 1;
688         out_ = (lv + noise) ^ noise;
689
690         dbgopout_ = out_;
691         return out_;
692 }
693
694 //      OP (FB) \8cv\8eZ
695 //      Self Feedback \82Ì\95Ï\92²\8dÅ\91å = 4\83Î
696 inline FM::ISample FM::Operator::CalcFB(uint fb)
697 {
698         EGStep();
699
700         ISample in = out_ + out2_;
701         out2_ = out_;
702
703         int pgin = PGCalc() >> (20+FM_PGBITS-FM_OPSINBITS);
704         if (fb < 31)
705         {
706                 pgin += ((in << (1 + IS2EC_SHIFT)) >> fb) >> (20+FM_PGBITS-FM_OPSINBITS);
707         }
708         out_ = LogToLin(eg_out_ + SINE(pgin));
709         dbgopout_ = out2_;
710
711         return out2_;
712 }
713
714 inline FM::ISample FM::Operator::CalcFBL(uint fb)
715 {
716         EGStep();
717         
718         ISample in = out_ + out2_;
719         out2_ = out_;
720
721         int pgin = PGCalcL() >> (20+FM_PGBITS-FM_OPSINBITS);
722         if (fb < 31)
723         {
724                 pgin += ((in << (1 + IS2EC_SHIFT)) >> fb) >> (20+FM_PGBITS-FM_OPSINBITS);
725         }
726
727         out_ = LogToLin(eg_out_ + SINE(pgin) + ams_[chip_->GetAML()]);
728         dbgopout_ = out_;
729
730         return out_;
731 }
732
733 // ---------------------------------------------------------------------------
734 //      \83X\83e\81[\83g\83Z\81[\83u
735 //
736 #define OPERATOR_STATE_VERSION  1
737
738 void Operator::SaveState(void *f)
739 {
740         FILEIO *state_fio = (FILEIO *)f;
741         
742         state_fio->FputUint32(OPERATOR_STATE_VERSION);
743         
744         state_fio->FputInt32(out_);
745         state_fio->FputInt32(out2_);
746         state_fio->FputInt32(in2_);
747         state_fio->FputUint32(dp_);
748         state_fio->FputUint32(detune_);
749         state_fio->FputUint32(detune2_);
750         state_fio->FputUint32(multiple_);
751         state_fio->FputUint32(pg_count_);
752         state_fio->FputUint32(pg_diff_);
753         state_fio->FputInt32(pg_diff_lfo_);
754         state_fio->FputUint32(bn_);
755         state_fio->FputInt32(eg_level_);
756         state_fio->FputInt32(eg_level_on_next_phase_);
757         state_fio->FputInt32(eg_count_);
758         state_fio->FputInt32(eg_count_diff_);
759         state_fio->FputInt32(eg_out_);
760         state_fio->FputInt32(tl_out_);
761         state_fio->FputInt32(eg_rate_);
762         state_fio->FputInt32(eg_curve_count_);
763         state_fio->FputInt32(ssg_offset_);
764         state_fio->FputInt32(ssg_vector_);
765         state_fio->FputInt32(ssg_phase_);
766         state_fio->FputUint32(key_scale_rate_);
767         state_fio->FputInt32(static_cast<int>(eg_phase_));
768         state_fio->FputInt32((int)(ams_ - &amtable[0][0][0]));
769         state_fio->FputUint32(ms_);
770         state_fio->FputUint32(tl_);
771         state_fio->FputUint32(tl_latch_);
772         state_fio->FputUint32(ar_);
773         state_fio->FputUint32(dr_);
774         state_fio->FputUint32(sr_);
775         state_fio->FputUint32(sl_);
776         state_fio->FputUint32(rr_);
777         state_fio->FputUint32(ks_);
778         state_fio->FputUint32(ssg_type_);
779         state_fio->FputBool(keyon_);
780         state_fio->FputBool(amon_);
781         state_fio->FputBool(param_changed_);
782         state_fio->FputBool(mute_);
783         state_fio->FputInt32(dbgopout_);
784         state_fio->FputInt32(dbgpgout_);
785 }
786
787 bool Operator::LoadState(void *f)
788 {
789         FILEIO *state_fio = (FILEIO *)f;
790         
791         if(state_fio->FgetUint32() != OPERATOR_STATE_VERSION) {
792                 return false;
793         }
794         out_ = state_fio->FgetInt32();
795         out2_ = state_fio->FgetInt32();
796         in2_ = state_fio->FgetInt32();
797         dp_ = state_fio->FgetUint32();
798         detune_ = state_fio->FgetUint32();
799         detune2_ = state_fio->FgetUint32();
800         multiple_ = state_fio->FgetUint32();
801         pg_count_ = state_fio->FgetUint32();
802         pg_diff_ = state_fio->FgetUint32();
803         pg_diff_lfo_ = state_fio->FgetInt32();
804         bn_ = state_fio->FgetUint32();
805         eg_level_ = state_fio->FgetInt32();
806         eg_level_on_next_phase_ = state_fio->FgetInt32();
807         eg_count_ = state_fio->FgetInt32();
808         eg_count_diff_ = state_fio->FgetInt32();
809         eg_out_ = state_fio->FgetInt32();
810         tl_out_ = state_fio->FgetInt32();
811         eg_rate_ = state_fio->FgetInt32();
812         eg_curve_count_ = state_fio->FgetInt32();
813         ssg_offset_ = state_fio->FgetInt32();
814         ssg_vector_ = state_fio->FgetInt32();
815         ssg_phase_ = state_fio->FgetInt32();
816         key_scale_rate_ = state_fio->FgetUint32();
817         eg_phase_ = static_cast<EGPhase>(state_fio->FgetInt32());
818         ams_ = &amtable[0][0][0] + state_fio->FgetInt32();
819         ms_ = state_fio->FgetUint32();
820         tl_ = state_fio->FgetUint32();
821         tl_latch_ = state_fio->FgetUint32();
822         ar_ = state_fio->FgetUint32();
823         dr_ = state_fio->FgetUint32();
824         sr_ = state_fio->FgetUint32();
825         sl_ = state_fio->FgetUint32();
826         rr_ = state_fio->FgetUint32();
827         ks_ = state_fio->FgetUint32();
828         ssg_type_ = state_fio->FgetUint32();
829         keyon_ = state_fio->FgetBool();
830         amon_ = state_fio->FgetBool();
831         param_changed_ = state_fio->FgetBool();
832         mute_ = state_fio->FgetBool();
833         dbgopout_ = state_fio->FgetInt32();
834         dbgpgout_ = state_fio->FgetInt32();
835         return true;
836 }
837
838 #undef Sine
839
840 // ---------------------------------------------------------------------------
841 //      4-op Channel
842 //
843 const uint8 Channel4::fbtable[8] = { 31, 7, 6, 5, 4, 3, 2, 1 };
844 int Channel4::kftable[64];
845
846 bool Channel4::tablehasmade = false;
847
848
849 Channel4::Channel4()
850 {
851         if (!tablehasmade)
852                 MakeTable();
853
854         SetAlgorithm(0);
855         pms = pmtable[0][0];
856 }
857
858 void Channel4::MakeTable()
859 {
860         // 100/64 cent =  2^(i*100/64*1200)
861         for (int i=0; i<64; i++)
862         {
863                 kftable[i] = int(0x10000 * pow(2., i / 768.) );
864         }
865 }
866
867 // \83\8a\83Z\83b\83g
868 void Channel4::Reset()
869 {
870         op[0].Reset();
871         op[1].Reset();
872         op[2].Reset();
873         op[3].Reset();
874 }
875
876 //      Calc \82Ì\97p\88Ó
877 int Channel4::Prepare()
878 {
879         op[0].Prepare();
880         op[1].Prepare();
881         op[2].Prepare();
882         op[3].Prepare();
883         
884         pms = pmtable[op[0].type_][op[0].ms_ & 7];
885         int key = (op[0].IsOn() | op[1].IsOn() | op[2].IsOn() | op[3].IsOn()) ? 1 : 0;
886         int lfo = op[0].ms_ & (op[0].amon_ | op[1].amon_ | op[2].amon_ | op[3].amon_ ? 0x37 : 7) ? 2 : 0;
887         return key | lfo;
888 }
889
890 //      F-Number/BLOCK \82ð\90Ý\92è
891 void Channel4::SetFNum(uint f)
892 {
893         for (int i=0; i<4; i++)
894                 op[i].SetFNum(f);
895 }
896
897 //      KC/KF \82ð\90Ý\92è
898 void Channel4::SetKCKF(uint kc, uint kf)
899 {
900         const static uint kctable[16] = 
901         { 
902                 5197, 5506, 5833, 6180, 6180, 6547, 6937, 7349, 
903                 7349, 7786, 8249, 8740, 8740, 9259, 9810, 10394, 
904         };
905
906         int oct = 19 - ((kc >> 4) & 7);
907
908 //printf("%p", this);
909         uint kcv = kctable[kc & 0x0f];
910         kcv = (kcv + 2) / 4 * 4;
911 //printf(" %.4x", kcv);
912         uint dp = kcv * kftable[kf & 0x3f];
913 //printf(" %.4x %.4x %.8x", kcv, kftable[kf & 0x3f], dp >> oct);
914         dp >>= 16 + 3;
915         dp <<= 16 + 3;
916         dp >>= oct;     
917         uint bn = (kc >> 2) & 31;
918         op[0].SetDPBN(dp, bn);
919         op[1].SetDPBN(dp, bn);
920         op[2].SetDPBN(dp, bn);
921         op[3].SetDPBN(dp, bn);
922 //printf(" %.8x\n", dp);
923 }
924
925 //      \83L\81[\90§\8cä
926 void Channel4::KeyControl(uint key)
927 {
928         if (key & 0x1) op[0].KeyOn(); else op[0].KeyOff();
929         if (key & 0x2) op[1].KeyOn(); else op[1].KeyOff();
930         if (key & 0x4) op[2].KeyOn(); else op[2].KeyOff();
931         if (key & 0x8) op[3].KeyOn(); else op[3].KeyOff();
932 }
933
934 //      \83A\83\8b\83S\83\8a\83Y\83\80\82ð\90Ý\92è
935 void Channel4::SetAlgorithm(uint algo)
936 {
937         static const uint8 table1[8][6] = 
938         {
939                 { 0, 1, 1, 2, 2, 3 },   { 1, 0, 0, 1, 1, 2 },
940                 { 1, 1, 1, 0, 0, 2 },   { 0, 1, 2, 1, 1, 2 },
941                 { 0, 1, 2, 2, 2, 1 },   { 0, 1, 0, 1, 0, 1 },
942                 { 0, 1, 2, 1, 2, 1 },   { 1, 0, 1, 0, 1, 0 },
943         };
944
945         in [0] = &buf[table1[algo][0]];
946         out[0] = &buf[table1[algo][1]];
947         in [1] = &buf[table1[algo][2]];
948         out[1] = &buf[table1[algo][3]];
949         in [2] = &buf[table1[algo][4]];
950         out[2] = &buf[table1[algo][5]];
951
952         op[0].ResetFB();
953         algo_ = algo;
954 }
955
956 //  \8d\87\90¬
957 ISample Channel4::Calc()
958 {
959         int r = 0;
960         switch (algo_)
961         {
962         case 0:
963                 op[2].Calc(op[1].Out());
964                 op[1].Calc(op[0].Out());
965                 r = op[3].Calc(op[2].Out());
966                 op[0].CalcFB(fb);
967                 break;
968         case 1:
969                 op[2].Calc(op[0].Out() + op[1].Out());
970                 op[1].Calc(0);
971                 r = op[3].Calc(op[2].Out());
972                 op[0].CalcFB(fb);
973                 break;
974         case 2:
975                 op[2].Calc(op[1].Out());
976                 op[1].Calc(0);
977                 r = op[3].Calc(op[0].Out() + op[2].Out());
978                 op[0].CalcFB(fb);
979                 break;
980         case 3:
981                 op[2].Calc(0);
982                 op[1].Calc(op[0].Out());
983                 r = op[3].Calc(op[1].Out() + op[2].Out());
984                 op[0].CalcFB(fb);
985                 break;
986         case 4:
987                 op[2].Calc(0);
988                 r = op[1].Calc(op[0].Out());
989                 r += op[3].Calc(op[2].Out());
990                 op[0].CalcFB(fb);
991                 break;
992         case 5:
993                 r =  op[2].Calc(op[0].Out());
994                 r += op[1].Calc(op[0].Out());
995                 r += op[3].Calc(op[0].Out());
996                 op[0].CalcFB(fb);
997                 break;
998         case 6:
999                 r  = op[2].Calc(0);
1000                 r += op[1].Calc(op[0].Out());
1001                 r += op[3].Calc(0);
1002                 op[0].CalcFB(fb);
1003                 break;
1004         case 7:
1005                 r  = op[2].Calc(0);
1006                 r += op[1].Calc(0);
1007                 r += op[3].Calc(0);
1008                 r += op[0].CalcFB(fb);
1009                 break;
1010         }
1011         return r;
1012 }
1013
1014 //  \8d\87\90¬
1015 ISample Channel4::CalcL()
1016 {
1017         chip_->SetPMV(pms[chip_->GetPML()]);
1018
1019         int r = 0;
1020         switch (algo_)
1021         {
1022         case 0:
1023                 op[2].CalcL(op[1].Out());
1024                 op[1].CalcL(op[0].Out());
1025                 r = op[3].CalcL(op[2].Out());
1026                 op[0].CalcFBL(fb);
1027                 break;
1028         case 1:
1029                 op[2].CalcL(op[0].Out() + op[1].Out());
1030                 op[1].CalcL(0);
1031                 r = op[3].CalcL(op[2].Out());
1032                 op[0].CalcFBL(fb);
1033                 break;
1034         case 2:
1035                 op[2].CalcL(op[1].Out());
1036                 op[1].CalcL(0);
1037                 r = op[3].CalcL(op[0].Out() + op[2].Out());
1038                 op[0].CalcFBL(fb);
1039                 break;
1040         case 3:
1041                 op[2].CalcL(0);
1042                 op[1].CalcL(op[0].Out());
1043                 r = op[3].CalcL(op[1].Out() + op[2].Out());
1044                 op[0].CalcFBL(fb);
1045                 break;
1046         case 4:
1047                 op[2].CalcL(0);
1048                 r = op[1].CalcL(op[0].Out());
1049                 r += op[3].CalcL(op[2].Out());
1050                 op[0].CalcFBL(fb);
1051                 break;
1052         case 5:
1053                 r =  op[2].CalcL(op[0].Out());
1054                 r += op[1].CalcL(op[0].Out());
1055                 r += op[3].CalcL(op[0].Out());
1056                 op[0].CalcFBL(fb);
1057                 break;
1058         case 6:
1059                 r  = op[2].CalcL(0);
1060                 r += op[1].CalcL(op[0].Out());
1061                 r += op[3].CalcL(0);
1062                 op[0].CalcFBL(fb);
1063                 break;
1064         case 7:
1065                 r  = op[2].CalcL(0);
1066                 r += op[1].CalcL(0);
1067                 r += op[3].CalcL(0);
1068                 r += op[0].CalcFBL(fb);
1069                 break;
1070         }
1071         return r;
1072 }
1073
1074 //  \8d\87\90¬
1075 ISample Channel4::CalcN(uint noise)
1076 {
1077         buf[1] = buf[2] = buf[3] = 0;
1078
1079         buf[0] = op[0].out_; op[0].CalcFB(fb);
1080         *out[0] += op[1].Calc(*in[0]);
1081         *out[1] += op[2].Calc(*in[1]);
1082         int o = op[3].out_;
1083         op[3].CalcN(noise);
1084         return *out[2] + o;
1085 }
1086
1087 //  \8d\87\90¬
1088 ISample Channel4::CalcLN(uint noise)
1089 {
1090         chip_->SetPMV(pms[chip_->GetPML()]);
1091         buf[1] = buf[2] = buf[3] = 0;
1092
1093         buf[0] = op[0].out_; op[0].CalcFBL(fb); 
1094         *out[0] += op[1].CalcL(*in[0]);
1095         *out[1] += op[2].CalcL(*in[1]);
1096         int o = op[3].out_;
1097         op[3].CalcN(noise);
1098         return *out[2] + o;
1099 }
1100
1101 // ---------------------------------------------------------------------------
1102 //      \83X\83e\81[\83g\83Z\81[\83u
1103 //
1104 #define CHANNEL4_STATE_VERSION  1
1105
1106 void Channel4::SaveState(void *f)
1107 {
1108         FILEIO *state_fio = (FILEIO *)f;
1109         
1110         state_fio->FputUint32(CHANNEL4_STATE_VERSION);
1111         
1112         state_fio->FputUint32(fb);
1113         state_fio->Fwrite(buf, sizeof(buf), 1);
1114         for(int i = 0; i < 3; i++) {
1115                 state_fio->FputInt32((int)(in [i] - &buf[0]));
1116                 state_fio->FputInt32((int)(out[i] - &buf[0]));
1117         }
1118         state_fio->FputInt32((int)(pms - &pmtable[0][0][0]));
1119         state_fio->FputInt32(algo_);
1120         for(int i = 0; i < 4; i++) {
1121                 op[i].SaveState(f);
1122         }
1123 }
1124
1125 bool Channel4::LoadState(void *f)
1126 {
1127         FILEIO *state_fio = (FILEIO *)f;
1128         
1129         if(state_fio->FgetUint32() != CHANNEL4_STATE_VERSION) {
1130                 return false;
1131         }
1132         fb = state_fio->FgetUint32();
1133         state_fio->Fread(buf, sizeof(buf), 1);
1134         for(int i = 0; i < 3; i++) {
1135                 in [i] = &buf[0] + state_fio->FgetInt32();
1136                 out[i] = &buf[0] + state_fio->FgetInt32();
1137         }
1138         pms = &pmtable[0][0][0] + state_fio->FgetInt32();
1139         algo_ = state_fio->FgetInt32();
1140         for(int i = 0; i < 4; i++) {
1141                 if(!op[i].LoadState(f)) {
1142                         return false;
1143                 }
1144         }
1145         return true;
1146 }
1147
1148 }       // namespace FM