summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/sound/scsplfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/sound/scsplfo.c')
-rw-r--r--trunk/src/emu/sound/scsplfo.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/trunk/src/emu/sound/scsplfo.c b/trunk/src/emu/sound/scsplfo.c
new file mode 100644
index 00000000000..ca658d1d4ec
--- /dev/null
+++ b/trunk/src/emu/sound/scsplfo.c
@@ -0,0 +1,160 @@
+/*
+ SCSP LFO handling
+
+ Part of the SCSP (YMF292-F) emulator package.
+ (not compiled directly, #included from scsp.c)
+
+ By ElSemi
+ MAME/M1 conversion and cleanup by R. Belmont
+*/
+
+#define LFO_SHIFT 8
+
+struct _LFO
+{
+ unsigned short phase;
+ UINT32 phase_step;
+ int *table;
+ int *scale;
+};
+
+#define LFIX(v) ((unsigned int) ((float) (1<<LFO_SHIFT)*(v)))
+
+//Convert DB to multiply amplitude
+#define DB(v) LFIX(pow(10.0,v/20.0))
+
+//Convert cents to step increment
+#define CENTS(v) LFIX(pow(2.0,v/1200.0))
+
+static int PLFO_TRI[256],PLFO_SQR[256],PLFO_SAW[256],PLFO_NOI[256];
+static int ALFO_TRI[256],ALFO_SQR[256],ALFO_SAW[256],ALFO_NOI[256];
+static const float LFOFreq[32]=
+{
+ 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,
+ 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
+};
+static const float ASCALE[8]={0.0f,0.4f,0.8f,1.5f,3.0f,6.0f,12.0f,24.0f};
+static const float PSCALE[8]={0.0f,7.0f,13.5f,27.0f,55.0f,112.0f,230.0f,494.0f};
+static int PSCALES[8][256];
+static int ASCALES[8][256];
+
+static void LFO_Init(running_machine &machine)
+{
+ int i,s;
+ for(i=0;i<256;++i)
+ {
+ int a,p;
+// float TL;
+ //Saw
+ a=255-i;
+ if(i<128)
+ p=i;
+ else
+ p=i-256;
+ ALFO_SAW[i]=a;
+ PLFO_SAW[i]=p;
+
+ //Square
+ if(i<128)
+ {
+ a=255;
+ p=127;
+ }
+ else
+ {
+ a=0;
+ p=-128;
+ }
+ ALFO_SQR[i]=a;
+ PLFO_SQR[i]=p;
+
+ //Tri
+ if(i<128)
+ a=255-(i*2);
+ else
+ a=(i*2)-256;
+ if(i<64)
+ p=i*2;
+ else if(i<128)
+ p=255-i*2;
+ else if(i<192)
+ p=256-i*2;
+ else
+ p=i*2-511;
+ ALFO_TRI[i]=a;
+ PLFO_TRI[i]=p;
+
+ //noise
+ //a=lfo_noise[i];
+ a=machine.rand()&0xff;
+ p=128-a;
+ ALFO_NOI[i]=a;
+ PLFO_NOI[i]=p;
+ }
+
+ for(s=0;s<8;++s)
+ {
+ float limit=PSCALE[s];
+ for(i=-128;i<128;++i)
+ {
+ PSCALES[s][i+128]=CENTS(((limit*(float) i)/128.0));
+ }
+ limit=-ASCALE[s];
+ for(i=0;i<256;++i)
+ {
+ ASCALES[s][i]=DB(((limit*(float) i)/256.0));
+ }
+ }
+}
+
+INLINE signed int PLFO_Step(struct _LFO *LFO)
+{
+ int p;
+ LFO->phase+=LFO->phase_step;
+#if LFO_SHIFT!=8
+ LFO->phase&=(1<<(LFO_SHIFT+8))-1;
+#endif
+ p=LFO->table[LFO->phase>>LFO_SHIFT];
+ p=LFO->scale[p+128];
+ return p<<(SHIFT-LFO_SHIFT);
+}
+
+INLINE signed int ALFO_Step(struct _LFO *LFO)
+{
+ int p;
+ LFO->phase+=LFO->phase_step;
+#if LFO_SHIFT!=8
+ LFO->phase&=(1<<(LFO_SHIFT+8))-1;
+#endif
+ p=LFO->table[LFO->phase>>LFO_SHIFT];
+ p=LFO->scale[p];
+ return p<<(SHIFT-LFO_SHIFT);
+}
+
+static void LFO_ComputeStep(struct _LFO *LFO,UINT32 LFOF,UINT32 LFOWS,UINT32 LFOS,int ALFO)
+{
+ float step=(float) LFOFreq[LFOF]*256.0/(float)44100;
+ LFO->phase_step=(unsigned int) ((float) (1<<LFO_SHIFT)*step);
+ if(ALFO)
+ {
+ switch(LFOWS)
+ {
+ case 0: LFO->table=ALFO_SAW; break;
+ case 1: LFO->table=ALFO_SQR; break;
+ case 2: LFO->table=ALFO_TRI; break;
+ case 3: LFO->table=ALFO_NOI; break;
+ }
+ LFO->scale=ASCALES[LFOS];
+ }
+ else
+ {
+ switch(LFOWS)
+ {
+ case 0: LFO->table=PLFO_SAW; break;
+ case 1: LFO->table=PLFO_SQR; break;
+ case 2: LFO->table=PLFO_TRI; break;
+ case 3: LFO->table=PLFO_NOI; break;
+ }
+ LFO->scale=PSCALES[LFOS];
+ }
+}