1 /*
2 SCSP LFO handling
3
4 Part of the SCSP (YMF292-F) emulator package.
5 (not compiled directly, #included from scsp.c)
6
7 By ElSemi
8 MAME/M1 conversion and cleanup by R. Belmont
9 */
10
11 #define LFO_SHIFT 8
12
13 struct _LFO
14 {
15 unsigned short phase;
16 UINT32 phase_step;
17 int *table;
18 int *scale;
19 };
20
21 #define LFIX(v) ((unsigned int) ((float) (1<<LFO_SHIFT)*(v)))
22
23 //Convert DB to multiply amplitude
24 #define DB(v) LFIX(pow(10.0,v/20.0))
25
26 //Convert cents to step increment
27 #define CENTS(v) LFIX(pow(2.0,v/1200.0))
28
29 static int PLFO_TRI[256],PLFO_SQR[256],PLFO_SAW[256],PLFO_NOI[256];
30 static int ALFO_TRI[256],ALFO_SQR[256],ALFO_SAW[256],ALFO_NOI[256];
31 static const float LFOFreq[32]=
32 {
33 0.17f,0.19f,0.23f,0.27f,0.34f,0.39f,0.45f,0.55f,0.68f,0.78f,0.92f,1.10f,1.39f,1.60f,1.87f,2.27f,
34 2.87f,3.31f,3.92f,4.79f,6.15f,7.18f,8.60f,10.8f,14.4f,17.2f,21.5f,28.7f,43.1f,57.4f,86.1f,172.3f
35 };
36 static const float ASCALE[8]={0.0f,0.4f,0.8f,1.5f,3.0f,6.0f,12.0f,24.0f};
37 static const float PSCALE[8]={0.0f,7.0f,13.5f,27.0f,55.0f,112.0f,230.0f,494.0f};
38 static int PSCALES[8][256];
39 static int ASCALES[8][256];
40 static UINT8 IsInit;
41
LFO_Init()42 static void LFO_Init(/*running_machine &machine*/)
43 {
44 int i,s;
45 if (IsInit)
46 return;
47 for(i=0;i<256;++i)
48 {
49 int a,p;
50 // float TL;
51 //Saw
52 a=255-i;
53 if(i<128)
54 p=i;
55 else
56 p=i-256;
57 ALFO_SAW[i]=a;
58 PLFO_SAW[i]=p;
59
60 //Square
61 if(i<128)
62 {
63 a=255;
64 p=127;
65 }
66 else
67 {
68 a=0;
69 p=-128;
70 }
71 ALFO_SQR[i]=a;
72 PLFO_SQR[i]=p;
73
74 //Tri
75 if(i<128)
76 a=255-(i*2);
77 else
78 a=(i*2)-256;
79 if(i<64)
80 p=i*2;
81 else if(i<128)
82 p=255-i*2;
83 else if(i<192)
84 p=256-i*2;
85 else
86 p=i*2-511;
87 ALFO_TRI[i]=a;
88 PLFO_TRI[i]=p;
89
90 //noise
91 //a=lfo_noise[i];
92 //a=machine.rand()&0xff;
93 a=rand()&0xff;
94 p=128-a;
95 ALFO_NOI[i]=a;
96 PLFO_NOI[i]=p;
97 }
98
99 for(s=0;s<8;++s)
100 {
101 float limit=PSCALE[s];
102 for(i=-128;i<128;++i)
103 {
104 PSCALES[s][i+128]=CENTS(((limit*(float) i)/128.0));
105 }
106 limit=-ASCALE[s];
107 for(i=0;i<256;++i)
108 {
109 ASCALES[s][i]=DB(((limit*(float) i)/256.0));
110 }
111 }
112 IsInit = 0x01;
113 }
114
PLFO_Step(struct _LFO * LFO)115 INLINE signed int PLFO_Step(struct _LFO *LFO)
116 {
117 int p;
118 LFO->phase+=LFO->phase_step;
119 #if LFO_SHIFT!=8
120 LFO->phase&=(1<<(LFO_SHIFT+8))-1;
121 #endif
122 p=LFO->table[LFO->phase>>LFO_SHIFT];
123 p=LFO->scale[p+128];
124 return p<<(SHIFT-LFO_SHIFT);
125 }
126
ALFO_Step(struct _LFO * LFO)127 INLINE signed int ALFO_Step(struct _LFO *LFO)
128 {
129 int p;
130 LFO->phase+=LFO->phase_step;
131 #if LFO_SHIFT!=8
132 LFO->phase&=(1<<(LFO_SHIFT+8))-1;
133 #endif
134 p=LFO->table[LFO->phase>>LFO_SHIFT];
135 p=LFO->scale[p];
136 return p<<(SHIFT-LFO_SHIFT);
137 }
138
LFO_ComputeStep(struct _LFO * LFO,UINT32 LFOF,UINT32 LFOWS,UINT32 LFOS,int ALFO)139 static void LFO_ComputeStep(struct _LFO *LFO,UINT32 LFOF,UINT32 LFOWS,UINT32 LFOS,int ALFO)
140 {
141 float step=(float) LFOFreq[LFOF]*256.0/(float)44100;
142 LFO->phase_step=(unsigned int) ((float) (1<<LFO_SHIFT)*step);
143 if(ALFO)
144 {
145 switch(LFOWS)
146 {
147 case 0: LFO->table=ALFO_SAW; break;
148 case 1: LFO->table=ALFO_SQR; break;
149 case 2: LFO->table=ALFO_TRI; break;
150 case 3: LFO->table=ALFO_NOI; break;
151 }
152 LFO->scale=ASCALES[LFOS];
153 }
154 else
155 {
156 switch(LFOWS)
157 {
158 case 0: LFO->table=PLFO_SAW; break;
159 case 1: LFO->table=PLFO_SQR; break;
160 case 2: LFO->table=PLFO_TRI; break;
161 case 3: LFO->table=PLFO_NOI; break;
162 }
163 LFO->scale=PSCALES[LFOS];
164 }
165 }
166