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     data32_t 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 float LFOFreq[32]={0.17,0.19,0.23,0.27,0.34,0.39,0.45,0.55,0.68,0.78,0.92,1.10,1.39,1.60,1.87,2.27,
32 			  2.87,3.31,3.92,4.79,6.15,7.18,8.60,10.8,14.4,17.2,21.5,28.7,43.1,57.4,86.1,172.3};
33 static float ASCALE[8]={0.0,0.4,0.8,1.5,3.0,6.0,12.0,24.0};
34 static float PSCALE[8]={0.0,7.0,13.5,27.0,55.0,112.0,230.0,494};
35 static int PSCALES[8][256];
36 static int ASCALES[8][256];
37 
LFO_Init(void)38 void LFO_Init(void)
39 {
40     int i,s;
41     for(i=0;i<256;++i)
42     {
43 		int a,p;
44 //		float TL;
45 		//Saw
46 		a=255-i;
47 		if(i<128)
48 			p=i;
49 		else
50 			p=255-i;
51 		ALFO_SAW[i]=a;
52 		PLFO_SAW[i]=p;
53 
54 		//Square
55 		if(i<128)
56 		{
57 			a=255;
58 			p=127;
59 		}
60 		else
61 		{
62 			a=0;
63 			p=-128;
64 		}
65 		ALFO_SQR[i]=a;
66 		PLFO_SQR[i]=p;
67 
68 		//Tri
69 		if(i<128)
70 			a=255-(i*2);
71 		else
72 			a=(i*2)-256;
73 		if(i<64)
74 			p=i*2;
75 		else if(i<128)
76 			p=255-i*2;
77 		else if(i<192)
78 			p=256-i*2;
79 		else
80 			p=i*2-511;
81 		ALFO_TRI[i]=a;
82 		PLFO_TRI[i]=p;
83 
84 		//noise
85 		//a=lfo_noise[i];
86 		a=rand()&0xff;
87 		p=128-a;
88 		ALFO_NOI[i]=a;
89 		PLFO_NOI[i]=p;
90     }
91 
92 	for(s=0;s<8;++s)
93 	{
94 		float limit=PSCALE[s];
95 		for(i=-128;i<128;++i)
96 		{
97 			PSCALES[s][i+128]=CENTS(((limit*(float) i)/128.0));
98 		}
99 		limit=-ASCALE[s];
100 		for(i=0;i<256;++i)
101 		{
102 			ASCALES[s][i]=DB(((limit*(float) i)/256.0));
103 		}
104 	}
105 }
106 
PLFO_Step(struct _LFO * LFO)107 static INLINE signed int PLFO_Step(struct _LFO *LFO)
108 {
109 	int p;
110     LFO->phase+=LFO->phase_step;
111 #if LFO_SHIFT!=8
112     LFO->phase&=(1<<(LFO_SHIFT+8))-1;
113 #endif
114     p=LFO->table[LFO->phase>>LFO_SHIFT];
115 	p=LFO->scale[p+128];
116 	return p<<(SHIFT-LFO_SHIFT);
117 }
118 
ALFO_Step(struct _LFO * LFO)119 static INLINE signed int ALFO_Step(struct _LFO *LFO)
120 {
121 	int p;
122     LFO->phase+=LFO->phase_step;
123 #if LFO_SHIFT!=8
124     LFO->phase&=(1<<(LFO_SHIFT+8))-1;
125 #endif
126     p=LFO->table[LFO->phase>>LFO_SHIFT];
127 	p=LFO->scale[p];
128 	return p<<(SHIFT-LFO_SHIFT);
129 }
130 
LFO_ComputeStep(struct _LFO * LFO,data32_t LFOF,data32_t LFOWS,data32_t LFOS,int ALFO)131 void LFO_ComputeStep(struct _LFO *LFO,data32_t LFOF,data32_t LFOWS,data32_t LFOS,int ALFO)
132 {
133     float step=(float) LFOFreq[LFOF]*256.0/(float)Machine->sample_rate;
134     LFO->phase_step=(unsigned int) ((float) (1<<LFO_SHIFT)*step);
135     if(ALFO)
136     {
137 		switch(LFOWS)
138 		{
139 			case 0: LFO->table=ALFO_SAW; break;
140 			case 1: LFO->table=ALFO_SQR; break;
141 			case 2: LFO->table=ALFO_TRI; break;
142 			case 3: LFO->table=ALFO_NOI; break;
143 		}
144 		LFO->scale=ASCALES[LFOS];
145 	}
146 	else
147 	{
148 		switch(LFOWS)
149 		{
150 		    case 0: LFO->table=PLFO_SAW; break;
151 		    case 1: LFO->table=PLFO_SQR; break;
152 			case 2: LFO->table=PLFO_TRI; break;
153 		    case 3: LFO->table=PLFO_NOI; break;
154 		}
155 		LFO->scale=PSCALES[LFOS];
156 	}
157 }
158