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